diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index bec23a20ac49a..167705235d516 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 4fdf32b60923c..8869477231d51 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 }