summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2021-12-30 23:57:21 +0100
committerBenjamin Kramer <benny.kra@googlemail.com>2022-01-04 16:58:05 +0100
commitea75be3d9df448b6abafaf752a8141764d93ca33 (patch)
treeee488166c6e38d7ef1864997575b5039cb960ac3
parent8aea5d5951dc7d2130ad671423830a45e215c540 (diff)
downloadllvm-ea75be3d9df448b6abafaf752a8141764d93ca33.tar.gz
[InferAttrs] Add writeonly to all the math functions
All of these functions would be `readnone`, but can't be on platforms where they can set `errno`. A `writeonly` function with no pointer arguments can only write (but never read) global state. Writeonly theoretically allows these calls to be CSE'd (a writeonly call with the same arguments will always result in the same global stores) or hoisted out of loops, but that's not implemented currently. There are a few functions in this list that could be `readnone` instead of `writeonly`, if someone is interested. Differential Revision: https://reviews.llvm.org/D116426
-rw-r--r--llvm/lib/Transforms/Utils/BuildLibCalls.cpp10
-rw-r--r--llvm/test/Transforms/InferFunctionAttrs/annotate.ll231
2 files changed, 126 insertions, 115 deletions
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index bec23a20ac49..167705235d51 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -34,6 +34,7 @@ STATISTIC(NumReadNone, "Number of functions inferred as readnone");
STATISTIC(NumInaccessibleMemOnly,
"Number of functions inferred as inaccessiblememonly");
STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
+STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");
STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
STATISTIC(NumInaccessibleMemOrArgMemOnly,
"Number of functions inferred as inaccessiblemem_or_argmemonly");
@@ -71,6 +72,14 @@ static bool setOnlyReadsMemory(Function &F) {
return true;
}
+static bool setDoesNotReadMemory(Function &F) {
+ if (F.doesNotReadMemory()) // writeonly or readnone
+ return false;
+ F.setDoesNotReadMemory();
+ ++NumWriteOnly;
+ return true;
+}
+
static bool setOnlyAccessesArgMemory(Function &F) {
if (F.onlyAccessesArgMemory())
return false;
@@ -1171,6 +1180,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_truncl:
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotFreeMemory(F);
+ Changed |= setDoesNotReadMemory(F);
Changed |= setWillReturn(F);
return Changed;
default:
diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index 4fdf32b60923..8869477231d5 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -195,76 +195,76 @@ declare double @__sinpi(double)
; CHECK: declare float @__sinpif(float)
declare float @__sinpif(float)
-; CHECK: declare i32 @abs(i32) [[NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
+; CHECK: declare i32 @abs(i32) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY:#[0-9]+]]
declare i32 @abs(i32)
; CHECK: declare noundef i32 @access(i8* nocapture noundef readonly, i32 noundef) [[NOFREE_NOUNWIND:#[0-9]+]]
declare i32 @access(i8*, i32)
-; CHECK: declare double @acos(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @acos(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @acos(double)
-; CHECK: declare float @acosf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @acosf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @acosf(float)
-; CHECK: declare double @acosh(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @acosh(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @acosh(double)
-; CHECK: declare float @acoshf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @acoshf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @acoshf(float)
-; CHECK: declare x86_fp80 @acoshl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @acoshl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @acoshl(x86_fp80)
-; CHECK: declare x86_fp80 @acosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @acosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @acosl(x86_fp80)
; CHECK: declare noalias noundef i8* @aligned_alloc(i64 noundef, i64 noundef) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
declare i8* @aligned_alloc(i64, i64)
-; CHECK: declare double @asin(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @asin(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @asin(double)
-; CHECK: declare float @asinf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @asinf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @asinf(float)
-; CHECK: declare double @asinh(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @asinh(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @asinh(double)
-; CHECK: declare float @asinhf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @asinhf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @asinhf(float)
-; CHECK: declare x86_fp80 @asinhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @asinhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @asinhl(x86_fp80)
-; CHECK: declare x86_fp80 @asinl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @asinl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @asinl(x86_fp80)
-; CHECK: declare double @atan(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @atan(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @atan(double)
-; CHECK: declare double @atan2(double, double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @atan2(double, double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @atan2(double, double)
-; CHECK: declare float @atan2f(float, float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @atan2f(float, float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @atan2f(float, float)
-; CHECK: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @atan2l(x86_fp80, x86_fp80)
-; CHECK: declare float @atanf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @atanf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @atanf(float)
-; CHECK: declare double @atanh(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @atanh(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @atanh(double)
-; CHECK: declare float @atanhf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @atanhf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @atanhf(float)
-; CHECK: declare x86_fp80 @atanhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @atanhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @atanhl(x86_fp80)
-; CHECK: declare x86_fp80 @atanl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @atanl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @atanl(x86_fp80)
; CHECK: declare double @atof(i8* nocapture) [[NOFREE_NOUNWIND_READONLY_WILLRETURN:#[0-9]+]]
@@ -289,25 +289,25 @@ declare void @bcopy(i8*, i8*, i64)
; CHECK: declare void @bzero(i8* nocapture writeonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
declare void @bzero(i8*, i64)
-; CHECK: declare noalias noundef i8* @calloc(i64 noundef, i64 noundef) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare noalias noundef i8* @calloc(i64 noundef, i64 noundef) [[NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
declare i8* @calloc(i64, i64)
-; CHECK: declare double @cbrt(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @cbrt(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @cbrt(double)
-; CHECK: declare float @cbrtf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @cbrtf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @cbrtf(float)
-; CHECK: declare x86_fp80 @cbrtl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @cbrtl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @cbrtl(x86_fp80)
-; CHECK: declare double @ceil(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @ceil(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @ceil(double)
-; CHECK: declare float @ceilf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @ceilf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @ceilf(float)
-; CHECK: declare x86_fp80 @ceill(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @ceill(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @ceill(x86_fp80)
; CHECK: declare noundef i32 @chmod(i8* nocapture noundef readonly, i16 noundef zeroext) [[NOFREE_NOUNWIND]]
@@ -322,70 +322,70 @@ declare void @clearerr(%opaque*)
; CHECK: declare noundef i32 @closedir(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
declare i32 @closedir(%opaque*)
-; CHECK: declare double @copysign(double, double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @copysign(double, double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @copysign(double, double)
-; CHECK: declare float @copysignf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @copysignf(float, float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @copysignf(float, float)
-; CHECK: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @copysignl(x86_fp80, x86_fp80)
-; CHECK: declare double @cos(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @cos(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @cos(double)
-; CHECK: declare float @cosf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @cosf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @cosf(float)
-; CHECK: declare double @cosh(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @cosh(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @cosh(double)
-; CHECK: declare float @coshf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @coshf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @coshf(float)
-; CHECK: declare x86_fp80 @coshl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @coshl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @coshl(x86_fp80)
-; CHECK: declare x86_fp80 @cosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @cosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @cosl(x86_fp80)
; CHECK: declare noundef i8* @ctermid(i8* nocapture noundef) [[NOFREE_NOUNWIND]]
declare i8* @ctermid(i8*)
-; CHECK: declare double @exp(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @exp(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @exp(double)
-; CHECK: declare double @exp2(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @exp2(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @exp2(double)
-; CHECK: declare float @exp2f(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @exp2f(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @exp2f(float)
-; CHECK: declare x86_fp80 @exp2l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @exp2l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @exp2l(x86_fp80)
-; CHECK: declare float @expf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @expf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @expf(float)
-; CHECK: declare x86_fp80 @expl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @expl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @expl(x86_fp80)
-; CHECK: declare double @expm1(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @expm1(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @expm1(double)
-; CHECK: declare float @expm1f(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @expm1f(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @expm1f(float)
-; CHECK: declare x86_fp80 @expm1l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @expm1l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @expm1l(x86_fp80)
-; CHECK: declare double @fabs(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @fabs(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @fabs(double)
-; CHECK: declare float @fabsf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @fabsf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @fabsf(float)
-; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @fabsl(x86_fp80)
; CHECK: declare noundef i32 @fclose(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
@@ -403,14 +403,14 @@ declare i32 @ferror(%opaque*)
; CHECK: declare noundef i32 @fflush(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
declare i32 @fflush(%opaque*)
-; CHECK: declare i32 @ffs(i32) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i32 @ffs(i32) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare i32 @ffs(i32)
-; CHECK-KNOWN: declare i32 @ffsl(i64) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK-KNOWN: declare i32 @ffsl(i64) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
; CHECK-UNKNOWN: declare i32 @ffsl(i64){{$}}
declare i32 @ffsl(i64)
-; CHECK-KNOWN: declare i32 @ffsll(i64) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK-KNOWN: declare i32 @ffsll(i64) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
; CHECK-UNKNOWN: declare i32 @ffsll(i64){{$}}
declare i32 @ffsll(i64)
@@ -429,13 +429,13 @@ declare i32 @fileno(%opaque*)
; CHECK: declare void @flockfile(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
declare void @flockfile(%opaque*)
-; CHECK: declare double @floor(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @floor(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @floor(double)
-; CHECK: declare float @floorf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @floorf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @floorf(float)
-; CHECK: declare x86_fp80 @floorl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @floorl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @floorl(x86_fp80)
; CHECK: declare i32 @fls(i32)
@@ -447,31 +447,31 @@ declare i32 @flsl(i64)
; CHECK: declare i32 @flsll(i64)
declare i32 @flsll(i64)
-; CHECK: declare double @fmax(double, double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @fmax(double, double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @fmax(double, double)
-; CHECK: declare float @fmaxf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @fmaxf(float, float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @fmaxf(float, float)
-; CHECK: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @fmaxl(x86_fp80, x86_fp80)
-; CHECK: declare double @fmin(double, double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @fmin(double, double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @fmin(double, double)
-; CHECK: declare float @fminf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @fminf(float, float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @fminf(float, float)
-; CHECK: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @fminl(x86_fp80, x86_fp80)
-; CHECK: declare double @fmod(double, double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @fmod(double, double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @fmod(double, double)
-; CHECK: declare float @fmodf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @fmodf(float, float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @fmodf(float, float)
-; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @fmodl(x86_fp80, x86_fp80)
; CHECK: declare noalias noundef %opaque* @fopen(i8* nocapture noundef readonly, i8* nocapture noundef readonly) [[NOFREE_NOUNWIND]]
@@ -578,13 +578,13 @@ declare i8* @gets(i8*)
; CHECK: declare noundef i32 @gettimeofday(%opaque* nocapture noundef, i8* nocapture noundef) [[NOFREE_NOUNWIND]]
declare i32 @gettimeofday(%opaque*, i8*)
-; CHECK: declare i32 @isascii(i32) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i32 @isascii(i32) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare i32 @isascii(i32)
-; CHECK: declare i32 @isdigit(i32) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i32 @isdigit(i32) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare i32 @isdigit(i32)
-; CHECK: declare i64 @labs(i64) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i64 @labs(i64) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare i64 @labs(i64)
; CHECK: declare noundef i32 @lchown(i8* nocapture noundef readonly, i32 noundef, i32 noundef) [[NOFREE_NOUNWIND]]
@@ -599,52 +599,52 @@ declare float @ldexpf(float, i32)
; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32 signext) [[NOFREE_WILLRETURN]]
declare x86_fp80 @ldexpl(x86_fp80, i32)
-; CHECK: declare i64 @llabs(i64) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i64 @llabs(i64) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare i64 @llabs(i64)
-; CHECK: declare double @log(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @log(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @log(double)
-; CHECK: declare double @log10(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @log10(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @log10(double)
-; CHECK: declare float @log10f(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @log10f(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @log10f(float)
-; CHECK: declare x86_fp80 @log10l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @log10l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @log10l(x86_fp80)
-; CHECK: declare double @log1p(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @log1p(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @log1p(double)
-; CHECK: declare float @log1pf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @log1pf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @log1pf(float)
-; CHECK: declare x86_fp80 @log1pl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @log1pl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @log1pl(x86_fp80)
-; CHECK: declare double @log2(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @log2(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @log2(double)
-; CHECK: declare float @log2f(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @log2f(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @log2f(float)
-; CHECK: declare x86_fp80 @log2l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @log2l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @log2l(x86_fp80)
-; CHECK: declare double @logb(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @logb(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @logb(double)
-; CHECK: declare float @logbf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @logbf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @logbf(float)
-; CHECK: declare x86_fp80 @logbl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @logbl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @logbl(x86_fp80)
-; CHECK: declare float @logf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @logf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @logf(float)
-; CHECK: declare x86_fp80 @logl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @logl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @logl(x86_fp80)
; CHECK: declare noundef i32 @lstat(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
@@ -703,13 +703,13 @@ declare float @modff(float, float*)
; CHECK: declare x86_fp80 @modfl(x86_fp80, x86_fp80* nocapture) [[NOFREE_NOUNWIND_WILLRETURN]]
declare x86_fp80 @modfl(x86_fp80, x86_fp80*)
-; CHECK: declare double @nearbyint(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @nearbyint(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @nearbyint(double)
-; CHECK: declare float @nearbyintf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @nearbyintf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @nearbyintf(float)
-; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @nearbyintl(x86_fp80)
; CHECK-LINUX: declare noundef i32 @open(i8* nocapture noundef readonly, i32 noundef, ...) [[NOFREE]]
@@ -734,13 +734,13 @@ declare %opaque* @popen(i8*, i8*)
; CHECK: declare i32 @posix_memalign(i8**, i64, i64) [[NOFREE]]
declare i32 @posix_memalign(i8**, i64, i64)
-; CHECK: declare double @pow(double, double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @pow(double, double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @pow(double, double)
-; CHECK: declare float @powf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @powf(float, float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @powf(float, float)
-; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @powl(x86_fp80, x86_fp80)
; CHECK: declare noundef i64 @pread(i32 noundef, i8* nocapture noundef, i64 noundef, i64 noundef) [[NOFREE]]
@@ -792,25 +792,25 @@ declare i32 @rename(i8*, i8*)
; CHECK: declare void @rewind(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
declare void @rewind(%opaque*)
-; CHECK: declare double @rint(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @rint(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @rint(double)
-; CHECK: declare float @rintf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @rintf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @rintf(float)
-; CHECK: declare x86_fp80 @rintl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @rintl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @rintl(x86_fp80)
; CHECK: declare noundef i32 @rmdir(i8* nocapture noundef readonly) [[NOFREE_NOUNWIND]]
declare i32 @rmdir(i8*)
-; CHECK: declare double @round(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @round(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @round(double)
-; CHECK: declare float @roundf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @roundf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @roundf(float)
-; CHECK: declare x86_fp80 @roundl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @roundl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @roundl(x86_fp80)
; CHECK: declare noundef i32 @scanf(i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]]
@@ -825,22 +825,22 @@ declare i32 @setitimer(i32, %opaque*, %opaque*)
; CHECK: declare noundef i32 @setvbuf(%opaque* nocapture noundef, i8* noundef, i32 noundef, i64 noundef) [[NOFREE_NOUNWIND]]
declare i32 @setvbuf(%opaque*, i8*, i32, i64)
-; CHECK: declare double @sin(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @sin(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @sin(double)
-; CHECK: declare float @sinf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @sinf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @sinf(float)
-; CHECK: declare double @sinh(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @sinh(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @sinh(double)
-; CHECK: declare float @sinhf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @sinhf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @sinhf(float)
-; CHECK: declare x86_fp80 @sinhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @sinhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @sinhl(x86_fp80)
-; CHECK: declare x86_fp80 @sinl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @sinl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @sinl(x86_fp80)
; CHECK: declare noundef i32 @snprintf(i8* noalias nocapture noundef writeonly, i64 noundef, i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]]
@@ -849,13 +849,13 @@ declare i32 @snprintf(i8*, i64, i8*, ...)
; CHECK: declare noundef i32 @sprintf(i8* noalias nocapture noundef writeonly, i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]]
declare i32 @sprintf(i8*, i8*, ...)
-; CHECK: declare double @sqrt(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @sqrt(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @sqrt(double)
-; CHECK: declare float @sqrtf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @sqrtf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @sqrtf(float)
-; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @sqrtl(x86_fp80)
; CHECK: declare noundef i32 @sscanf(i8* nocapture noundef readonly, i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]]
@@ -969,22 +969,22 @@ declare i64 @strxfrm(i8*, i8*, i64)
; CHECK: declare noundef i32 @system(i8* nocapture noundef readonly) [[NOFREE]]
declare i32 @system(i8*)
-; CHECK: declare double @tan(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @tan(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @tan(double)
-; CHECK: declare float @tanf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @tanf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @tanf(float)
-; CHECK: declare double @tanh(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @tanh(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @tanh(double)
-; CHECK: declare float @tanhf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @tanhf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @tanhf(float)
-; CHECK: declare x86_fp80 @tanhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @tanhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @tanhl(x86_fp80)
-; CHECK: declare x86_fp80 @tanl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @tanl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @tanl(x86_fp80)
; CHECK: declare noundef i64 @times(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
@@ -996,16 +996,16 @@ declare %opaque* @tmpfile()
; CHECK-LINUX: declare noalias noundef %opaque* @tmpfile64() [[NOFREE_NOUNWIND]]
declare %opaque* @tmpfile64()
-; CHECK: declare i32 @toascii(i32) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i32 @toascii(i32) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare i32 @toascii(i32)
-; CHECK: declare double @trunc(double) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare double @trunc(double) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare double @trunc(double)
-; CHECK: declare float @truncf(float) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare float @truncf(float) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare float @truncf(float)
-; CHECK: declare x86_fp80 @truncl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare x86_fp80 @truncl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]]
declare x86_fp80 @truncl(x86_fp80)
; CHECK: declare noundef i32 @uname(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
@@ -1064,6 +1064,7 @@ declare void @memset_pattern16(i8*, i8*, i64)
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn }
+; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]] = { mustprogress nofree nounwind willreturn writeonly }
; CHECK-DAG: attributes [[NOFREE_NOUNWIND]] = { nofree nounwind }
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { inaccessiblememonly mustprogress nofree nounwind willreturn }
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind readonly willreturn }