diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -42,6 +42,7 @@ STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns"); STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns"); STATISTIC(NumReturnedArg, "Number of arguments inferred as returned"); +STATISTIC(NumWillReturn, "Number of functions inferred as willreturn"); static bool setDoesNotAccessMemory(Function &F) { if (F.doesNotAccessMemory()) @@ -181,6 +182,14 @@ return true; } +static bool setWillReturn(Function &F) { + if (F.hasFnAttribute(Attribute::WillReturn)) + return false; + F.addFnAttr(Attribute::WillReturn); + ++NumWillReturn; + return true; +} + bool llvm::inferLibFuncAttributes(Module *M, StringRef Name, const TargetLibraryInfo &TLI) { Function *F = M->getFunction(Name); @@ -208,6 +217,7 @@ Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_strchr: @@ -215,6 +225,7 @@ Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_strtol: case LibFunc_strtod: @@ -224,6 +235,7 @@ case LibFunc_strtold: case LibFunc_strtoull: Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); return Changed; @@ -231,12 +243,14 @@ case LibFunc_strncpy: case LibFunc_strcat: case LibFunc_strncat: + Changed |= setWillReturn(F); Changed |= setReturnedArg(F, 0); LLVM_FALLTHROUGH; case LibFunc_stpcpy: case LibFunc_stpncpy: Changed |= setOnlyAccessesArgMemory(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyWritesMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); @@ -245,6 +259,7 @@ return Changed; case LibFunc_strxfrm: Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); @@ -255,6 +270,7 @@ case LibFunc_strcspn: // 0,1 Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -266,6 +282,7 @@ // global memory. Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); return Changed; @@ -274,11 +291,13 @@ Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_strtok: case LibFunc_strtok_r: Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; @@ -298,6 +317,7 @@ case LibFunc_strndup: Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; @@ -338,6 +358,7 @@ case LibFunc_setitimer: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setDoesNotCapture(F, 2); Changed |= setOnlyReadsMemory(F, 1); @@ -352,11 +373,13 @@ Changed |= setRetNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_memcmp: Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); return Changed; @@ -365,16 +388,19 @@ Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_modf: case LibFunc_modff: case LibFunc_modfl: Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_memcpy: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotAlias(F, 0); Changed |= setReturnedArg(F, 0); Changed |= setOnlyWritesMemory(F, 0); @@ -385,6 +411,7 @@ case LibFunc_memmove: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setReturnedArg(F, 0); Changed |= setOnlyWritesMemory(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -394,6 +421,7 @@ case LibFunc_memccpy: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotAlias(F, 0); Changed |= setOnlyWritesMemory(F, 0); Changed |= setDoesNotAlias(F, 1); @@ -405,6 +433,7 @@ return Changed; case LibFunc_memalign: Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_mkdir: Changed |= setRetAndArgsNoUndef(F); @@ -415,16 +444,19 @@ case LibFunc_mktime: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_realloc: Changed |= setRetNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_reallocf: Changed |= setRetNoUndef(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_read: // May throw; "read" is a valid pthread cancellation point. @@ -469,10 +501,12 @@ Changed |= setRetNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_bcopy: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyWritesMemory(F, 1); @@ -482,12 +516,14 @@ Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_bzero: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyWritesMemory(F, 0); return Changed; @@ -495,6 +531,7 @@ Changed |= setRetNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); return Changed; case LibFunc_chmod: case LibFunc_chown: @@ -516,6 +553,7 @@ case LibFunc_atoll: Changed |= setDoesNotThrow(F); Changed |= setOnlyReadsMemory(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_access: @@ -548,6 +586,7 @@ case LibFunc_free: Changed |= setArgsNoUndef(F); Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_fseek: @@ -584,6 +623,7 @@ case LibFunc_frexpf: case LibFunc_frexpl: Changed |= setDoesNotThrow(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_fstatvfs: @@ -847,6 +887,7 @@ case LibFunc_dunder_strndup: Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; @@ -941,6 +982,7 @@ Changed |= setRetNoUndef(F); Changed |= setRetNonNull(F); Changed |= setRetDoesNotAlias(F); + Changed |= setWillReturn(F); return Changed; // TODO: add LibFunc entries for: // case LibFunc_memset_pattern4: @@ -952,6 +994,12 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; + case LibFunc_memset: + Changed |= setOnlyAccessesArgMemory(F); + Changed |= setWillReturn(F); + Changed |= setDoesNotThrow(F); + Changed |= setOnlyWritesMemory(F, 0); + return Changed; // int __nvvm_reflect(const char *) case LibFunc_nvvm_reflect: Changed |= setRetAndArgsNoUndef(F); @@ -962,6 +1010,134 @@ case LibFunc_ldexpf: case LibFunc_ldexpl: Changed |= setSignExtendedArg(F, 1); + Changed |= setWillReturn(F); + return Changed; + case LibFunc_abs: + case LibFunc_acos: + case LibFunc_acosf: + case LibFunc_acosh: + case LibFunc_acoshf: + case LibFunc_acoshl: + case LibFunc_acosl: + case LibFunc_asin: + case LibFunc_asinf: + case LibFunc_asinh: + case LibFunc_asinhf: + case LibFunc_asinhl: + case LibFunc_asinl: + case LibFunc_atan: + case LibFunc_atan2: + case LibFunc_atan2f: + case LibFunc_atan2l: + case LibFunc_atanf: + case LibFunc_atanh: + case LibFunc_atanhf: + case LibFunc_atanhl: + case LibFunc_atanl: + case LibFunc_cbrt: + case LibFunc_cbrtf: + case LibFunc_cbrtl: + case LibFunc_ceil: + case LibFunc_ceilf: + case LibFunc_ceill: + case LibFunc_copysign: + case LibFunc_copysignf: + case LibFunc_copysignl: + case LibFunc_cos: + case LibFunc_cosh: + case LibFunc_coshf: + case LibFunc_coshl: + case LibFunc_cosf: + case LibFunc_cosl: + case LibFunc_cospi: + case LibFunc_cospif: + case LibFunc_exp: + case LibFunc_expf: + case LibFunc_expl: + case LibFunc_exp2: + case LibFunc_exp2f: + case LibFunc_exp2l: + case LibFunc_expm1: + case LibFunc_expm1f: + case LibFunc_expm1l: + case LibFunc_fabs: + case LibFunc_fabsf: + case LibFunc_fabsl: + case LibFunc_ffs: + case LibFunc_ffsl: + case LibFunc_ffsll: + case LibFunc_floor: + case LibFunc_floorf: + case LibFunc_floorl: + case LibFunc_fls: + case LibFunc_flsl: + case LibFunc_flsll: + case LibFunc_fmax: + case LibFunc_fmaxf: + case LibFunc_fmaxl: + case LibFunc_fmin: + case LibFunc_fminf: + case LibFunc_fminl: + case LibFunc_fmod: + case LibFunc_fmodf: + case LibFunc_fmodl: + case LibFunc_isascii: + case LibFunc_isdigit: + case LibFunc_labs: + case LibFunc_llabs: + case LibFunc_log: + case LibFunc_log10: + case LibFunc_log10f: + case LibFunc_log10l: + case LibFunc_log1p: + case LibFunc_log1pf: + case LibFunc_log1pl: + case LibFunc_log2: + case LibFunc_log2f: + case LibFunc_log2l: + case LibFunc_logb: + case LibFunc_logbf: + case LibFunc_logbl: + case LibFunc_logf: + case LibFunc_logl: + case LibFunc_nearbyint: + case LibFunc_nearbyintf: + case LibFunc_nearbyintl: + case LibFunc_pow: + case LibFunc_powf: + case LibFunc_powl: + case LibFunc_rint: + case LibFunc_rintf: + case LibFunc_rintl: + case LibFunc_round: + case LibFunc_roundf: + case LibFunc_roundl: + case LibFunc_sin: + case LibFunc_sincospif_stret: + case LibFunc_sinf: + case LibFunc_sinh: + case LibFunc_sinhf: + case LibFunc_sinhl: + case LibFunc_sinl: + case LibFunc_sinpi: + case LibFunc_sinpif: + case LibFunc_sqrt: + case LibFunc_sqrtf: + case LibFunc_sqrtl: + case LibFunc_strnlen: + case LibFunc_tan: + case LibFunc_tanf: + case LibFunc_tanh: + case LibFunc_tanhf: + case LibFunc_tanhl: + case LibFunc_tanl: + case LibFunc_toascii: + case LibFunc_trunc: + case LibFunc_truncf: + case LibFunc_truncl: + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotFreeMemory(F); + Changed |= setWillReturn(F); return Changed; default: // FIXME: It'd be really nice to cover all the library functions we're diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll --- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -6,13 +6,13 @@ ; operator new routines declare i8* @_Znwj(i64 ) -; CHECK: declare noalias noundef nonnull i8* @_Znwj(i64) [[NOFREE:#[0-9]+]] +; CHECK: declare noalias noundef nonnull i8* @_Znwj(i64) [[NOFREE_WILLRETURN:#[0-9]+]] declare i8* @_Znwm(i64) -; CHECK: declare noalias noundef nonnull i8* @_Znwm(i64) [[NOFREE]] +; CHECK: declare noalias noundef nonnull i8* @_Znwm(i64) [[NOFREE_WILLRETURN]] declare i32 @__nvvm_reflect(i8*) -; CHECK-NVPTX: declare noundef i32 @__nvvm_reflect(i8* noundef) [[NOFREE:#[0-9]+]] -; CHECK-NVPTX: attributes [[NOFREE]] = { nofree nounwind readnone } +; CHECK-NVPTX: declare noundef i32 @__nvvm_reflect(i8* noundef) [[NOFREE_NOUNWIND_READNONE:#[0-9]+]] +; CHECK-NVPTX: attributes [[NOFREE_NOUNWIND_READNONE]] = { nofree nounwind readnone } ; Check all the libc functions (thereby also exercising the prototype check). @@ -160,73 +160,73 @@ ; CHECK: declare float @__sinpif(float) declare float @__sinpif(float) -; CHECK: declare i32 @abs(i32) [[NOFREE]] +; CHECK: declare i32 @abs(i32) [[NOFREE_NOUNWIND_WILLRETURN:#[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]] +; CHECK: declare double @acos(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @acos(double) -; CHECK: declare float @acosf(float) [[NOFREE]] +; CHECK: declare float @acosf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @acosf(float) -; CHECK: declare double @acosh(double) [[NOFREE]] +; CHECK: declare double @acosh(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @acosh(double) -; CHECK: declare float @acoshf(float) [[NOFREE]] +; CHECK: declare float @acoshf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @acoshf(float) -; CHECK: declare x86_fp80 @acoshl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @acoshl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @acoshl(x86_fp80) -; CHECK: declare x86_fp80 @acosl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @acosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @acosl(x86_fp80) -; CHECK: declare double @asin(double) [[NOFREE]] +; CHECK: declare double @asin(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @asin(double) -; CHECK: declare float @asinf(float) [[NOFREE]] +; CHECK: declare float @asinf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @asinf(float) -; CHECK: declare double @asinh(double) [[NOFREE]] +; CHECK: declare double @asinh(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @asinh(double) -; CHECK: declare float @asinhf(float) [[NOFREE]] +; CHECK: declare float @asinhf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @asinhf(float) -; CHECK: declare x86_fp80 @asinhl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @asinhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @asinhl(x86_fp80) -; CHECK: declare x86_fp80 @asinl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @asinl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @asinl(x86_fp80) -; CHECK: declare double @atan(double) [[NOFREE]] +; CHECK: declare double @atan(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @atan(double) -; CHECK: declare double @atan2(double, double) [[NOFREE]] +; CHECK: declare double @atan2(double, double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @atan2(double, double) -; CHECK: declare float @atan2f(float, float) [[NOFREE]] +; CHECK: declare float @atan2f(float, float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @atan2f(float, float) -; CHECK: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @atan2l(x86_fp80, x86_fp80) -; CHECK: declare float @atanf(float) [[NOFREE]] +; CHECK: declare float @atanf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @atanf(float) -; CHECK: declare double @atanh(double) [[NOFREE]] +; CHECK: declare double @atanh(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @atanh(double) -; CHECK: declare float @atanhf(float) [[NOFREE]] +; CHECK: declare float @atanhf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @atanhf(float) -; CHECK: declare x86_fp80 @atanhl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @atanhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @atanhl(x86_fp80) -; CHECK: declare x86_fp80 @atanl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @atanl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @atanl(x86_fp80) ; CHECK: declare double @atof(i8* nocapture) [[NOFREE_NOUNWIND_READONLY:#[0-9]+]] @@ -253,25 +253,25 @@ ; CHECK: declare void @bzero(i8* nocapture writeonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND:#[0-9]+]] declare void @bzero(i8*, i64) -; CHECK: declare noalias noundef i8* @calloc(i64, i64) [[NOFREE_NOUNWIND]] +; CHECK: declare noalias noundef i8* @calloc(i64, i64) [[NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]] declare i8* @calloc(i64, i64) -; CHECK: declare double @cbrt(double) [[NOFREE]] +; CHECK: declare double @cbrt(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @cbrt(double) -; CHECK: declare float @cbrtf(float) [[NOFREE]] +; CHECK: declare float @cbrtf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @cbrtf(float) -; CHECK: declare x86_fp80 @cbrtl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @cbrtl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @cbrtl(x86_fp80) -; CHECK: declare double @ceil(double) [[NOFREE]] +; CHECK: declare double @ceil(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @ceil(double) -; CHECK: declare float @ceilf(float) [[NOFREE]] +; CHECK: declare float @ceilf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @ceilf(float) -; CHECK: declare x86_fp80 @ceill(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @ceill(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @ceill(x86_fp80) ; CHECK: declare noundef i32 @chmod(i8* nocapture noundef readonly, i16 noundef zeroext) [[NOFREE_NOUNWIND]] @@ -286,70 +286,70 @@ ; CHECK: declare noundef i32 @closedir(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] declare i32 @closedir(%opaque*) -; CHECK: declare double @copysign(double, double) [[NOFREE]] +; CHECK: declare double @copysign(double, double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @copysign(double, double) -; CHECK: declare float @copysignf(float, float) [[NOFREE]] +; CHECK: declare float @copysignf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @copysignf(float, float) -; CHECK: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @copysignl(x86_fp80, x86_fp80) -; CHECK: declare double @cos(double) [[NOFREE]] +; CHECK: declare double @cos(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @cos(double) -; CHECK: declare float @cosf(float) [[NOFREE]] +; CHECK: declare float @cosf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @cosf(float) -; CHECK: declare double @cosh(double) [[NOFREE]] +; CHECK: declare double @cosh(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @cosh(double) -; CHECK: declare float @coshf(float) [[NOFREE]] +; CHECK: declare float @coshf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @coshf(float) -; CHECK: declare x86_fp80 @coshl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @coshl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @coshl(x86_fp80) -; CHECK: declare x86_fp80 @cosl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @cosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] 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]] +; CHECK: declare double @exp(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @exp(double) -; CHECK: declare double @exp2(double) [[NOFREE]] +; CHECK: declare double @exp2(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @exp2(double) -; CHECK: declare float @exp2f(float) [[NOFREE]] +; CHECK: declare float @exp2f(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @exp2f(float) -; CHECK: declare x86_fp80 @exp2l(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @exp2l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @exp2l(x86_fp80) -; CHECK: declare float @expf(float) [[NOFREE]] +; CHECK: declare float @expf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @expf(float) -; CHECK: declare x86_fp80 @expl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @expl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @expl(x86_fp80) -; CHECK: declare double @expm1(double) [[NOFREE]] +; CHECK: declare double @expm1(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @expm1(double) -; CHECK: declare float @expm1f(float) [[NOFREE]] +; CHECK: declare float @expm1f(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @expm1f(float) -; CHECK: declare x86_fp80 @expm1l(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @expm1l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @expm1l(x86_fp80) -; CHECK: declare double @fabs(double) [[NOFREE]] +; CHECK: declare double @fabs(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @fabs(double) -; CHECK: declare float @fabsf(float) [[NOFREE]] +; CHECK: declare float @fabsf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @fabsf(float) -; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @fabsl(x86_fp80) ; CHECK: declare noundef i32 @fclose(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] @@ -361,19 +361,19 @@ ; CHECK: declare noundef i32 @feof(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] declare i32 @feof(%opaque*) -; CHECK: declare noundef i32 @ferror(%opaque* nocapture noundef) [[NOFREE_NOUNWIND_READONLY]] +; CHECK: declare noundef i32 @ferror(%opaque* nocapture noundef) [[NOFREE_NOUNWIND_READONLY:#[0-9]+]] declare i32 @ferror(%opaque*) ; CHECK: declare noundef i32 @fflush(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] declare i32 @fflush(%opaque*) -; CHECK: declare i32 @ffs(i32) [[NOFREE]] +; CHECK: declare i32 @ffs(i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i32 @ffs(i32) -; CHECK: declare i32 @ffsl(i64) [[NOFREE]] +; CHECK: declare i32 @ffsl(i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i32 @ffsl(i64) -; CHECK: declare i32 @ffsll(i64) [[NOFREE]] +; CHECK: declare i32 @ffsll(i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i32 @ffsll(i64) ; CHECK: declare noundef i32 @fgetc(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] @@ -391,13 +391,13 @@ ; CHECK: declare void @flockfile(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] declare void @flockfile(%opaque*) -; CHECK: declare double @floor(double) [[NOFREE]] +; CHECK: declare double @floor(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @floor(double) -; CHECK: declare float @floorf(float) [[NOFREE]] +; CHECK: declare float @floorf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @floorf(float) -; CHECK: declare x86_fp80 @floorl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @floorl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @floorl(x86_fp80) ; CHECK: declare i32 @fls(i32) @@ -409,31 +409,31 @@ ; CHECK: declare i32 @flsll(i64) declare i32 @flsll(i64) -; CHECK: declare double @fmax(double, double) [[NOFREE]] +; CHECK: declare double @fmax(double, double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @fmax(double, double) -; CHECK: declare float @fmaxf(float, float) [[NOFREE]] +; CHECK: declare float @fmaxf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @fmaxf(float, float) -; CHECK: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) -; CHECK: declare double @fmin(double, double) [[NOFREE]] +; CHECK: declare double @fmin(double, double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @fmin(double, double) -; CHECK: declare float @fminf(float, float) [[NOFREE]] +; CHECK: declare float @fminf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @fminf(float, float) -; CHECK: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @fminl(x86_fp80, x86_fp80) -; CHECK: declare double @fmod(double, double) [[NOFREE]] +; CHECK: declare double @fmod(double, double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @fmod(double, double) -; CHECK: declare float @fmodf(float, float) [[NOFREE]] +; CHECK: declare float @fmodf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @fmodf(float, float) -; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @fmodl(x86_fp80, x86_fp80) ; CHECK: declare noalias noundef %opaque* @fopen(i8* nocapture noundef readonly, i8* nocapture noundef readonly) [[NOFREE_NOUNWIND]] @@ -454,13 +454,13 @@ ; CHECK: declare void @free(i8* nocapture noundef) [[NOUNWIND:#[0-9]+]] declare void @free(i8*) -; CHECK: declare double @frexp(double, i32* nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare double @frexp(double, i32* nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @frexp(double, i32*) -; CHECK: declare float @frexpf(float, i32* nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare float @frexpf(float, i32* nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @frexpf(float, i32*) -; CHECK: declare x86_fp80 @frexpl(x86_fp80, i32* nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare x86_fp80 @frexpl(x86_fp80, i32* nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @frexpl(x86_fp80, i32*) ; CHECK: declare noundef i32 @fscanf(%opaque* nocapture noundef, i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]] @@ -538,73 +538,73 @@ ; CHECK: declare noundef i32 @gettimeofday(%opaque* nocapture noundef, i8* nocapture noundef) [[NOFREE_NOUNWIND]] declare i32 @gettimeofday(%opaque*, i8*) -; CHECK: declare i32 @isascii(i32) [[NOFREE]] +; CHECK: declare i32 @isascii(i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i32 @isascii(i32) -; CHECK: declare i32 @isdigit(i32) [[NOFREE]] +; CHECK: declare i32 @isdigit(i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i32 @isdigit(i32) -; CHECK: declare i64 @labs(i64) [[NOFREE]] +; CHECK: declare i64 @labs(i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @labs(i64) ; CHECK: declare noundef i32 @lchown(i8* nocapture noundef readonly, i32 noundef, i32 noundef) [[NOFREE_NOUNWIND]] declare i32 @lchown(i8*, i32, i32) -; CHECK: declare double @ldexp(double, i32 signext) [[NOFREE]] +; CHECK: declare double @ldexp(double, i32 signext) [[NOFREE_WILLRETURN]] declare double @ldexp(double, i32) -; CHECK: declare float @ldexpf(float, i32 signext) [[NOFREE]] +; CHECK: declare float @ldexpf(float, i32 signext) [[NOFREE_WILLRETURN]] declare float @ldexpf(float, i32) -; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32 signext) [[NOFREE]] +; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32 signext) [[NOFREE_WILLRETURN]] declare x86_fp80 @ldexpl(x86_fp80, i32) -; CHECK: declare i64 @llabs(i64) [[NOFREE]] +; CHECK: declare i64 @llabs(i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @llabs(i64) -; CHECK: declare double @log(double) [[NOFREE]] +; CHECK: declare double @log(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @log(double) -; CHECK: declare double @log10(double) [[NOFREE]] +; CHECK: declare double @log10(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @log10(double) -; CHECK: declare float @log10f(float) [[NOFREE]] +; CHECK: declare float @log10f(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @log10f(float) -; CHECK: declare x86_fp80 @log10l(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @log10l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @log10l(x86_fp80) -; CHECK: declare double @log1p(double) [[NOFREE]] +; CHECK: declare double @log1p(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @log1p(double) -; CHECK: declare float @log1pf(float) [[NOFREE]] +; CHECK: declare float @log1pf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @log1pf(float) -; CHECK: declare x86_fp80 @log1pl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @log1pl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @log1pl(x86_fp80) -; CHECK: declare double @log2(double) [[NOFREE]] +; CHECK: declare double @log2(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @log2(double) -; CHECK: declare float @log2f(float) [[NOFREE]] +; CHECK: declare float @log2f(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @log2f(float) -; CHECK: declare x86_fp80 @log2l(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @log2l(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @log2l(x86_fp80) -; CHECK: declare double @logb(double) [[NOFREE]] +; CHECK: declare double @logb(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @logb(double) -; CHECK: declare float @logbf(float) [[NOFREE]] +; CHECK: declare float @logbf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @logbf(float) -; CHECK: declare x86_fp80 @logbl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @logbl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @logbl(x86_fp80) -; CHECK: declare float @logf(float) [[NOFREE]] +; CHECK: declare float @logf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @logf(float) -; CHECK: declare x86_fp80 @logl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @logl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @logl(x86_fp80) ; CHECK: declare noundef i32 @lstat(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND]] @@ -613,10 +613,10 @@ ; CHECK-LINUX: declare noundef i32 @lstat64(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND]] declare i32 @lstat64(i8*, %opaque*) -; CHECK: declare noalias noundef i8* @malloc(i64) [[NOFREE_NOUNWIND]] +; CHECK: declare noalias noundef i8* @malloc(i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i8* @malloc(i64) -; CHECK-LINUX: declare noalias i8* @memalign(i64, i64) [[NOFREE]] +; CHECK-LINUX: declare noalias i8* @memalign(i64, i64) [[NOFREE_WILLRETURN]] declare i8* @memalign(i64, i64) ; CHECK: declare i8* @memccpy(i8* noalias writeonly, i8* noalias nocapture readonly, i32, i64) [[ARGMEMONLY_NOFREE_NOUNWIND:#[0-9]+]] @@ -633,40 +633,44 @@ ; CHECK: declare i8* @memcpy(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]] declare i8* @memcpy(i8*, i8*, i64) +; CHECK-DARWIN: declare i8* @__memcpy_chk(i8*, i8*, i64, i64) [[NOFREE_NOUNWIND]] +; CHECK-LINUX: declare i8* @__memcpy_chk(i8*, i8*, i64, i64) [[NOFREE_NOUNWIND]] +declare i8* @__memcpy_chk(i8*, i8*, i64, i64) + ; CHECK: declare i8* @mempcpy(i8* noalias writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]] declare i8* @mempcpy(i8*, i8*, i64) ; CHECK: declare i8* @memmove(i8* returned writeonly, i8* nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]] declare i8* @memmove(i8*, i8*, i64) -; CHECK: declare i8* @memset(i8*, i32, i64) [[NOFREE]] +; CHECK: declare i8* @memset(i8* writeonly, i32, i64) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]] declare i8* @memset(i8*, i32, i64) ; CHECK: declare noundef i32 @mkdir(i8* nocapture noundef readonly, i16 noundef zeroext) [[NOFREE_NOUNWIND]] declare i32 @mkdir(i8*, i16 zeroext) -; CHECK: declare noundef i64 @mktime(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] +; CHECK: declare noundef i64 @mktime(%opaque* nocapture noundef) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @mktime(%opaque*) -; CHECK: declare double @modf(double, double* nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare double @modf(double, double* nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @modf(double, double*) -; CHECK: declare float @modff(float, float* nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare float @modff(float, float* nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @modff(float, float*) -; CHECK: declare x86_fp80 @modfl(x86_fp80, x86_fp80* nocapture) [[NOFREE_NOUNWIND]] +; 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]] +; CHECK: declare double @nearbyint(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @nearbyint(double) -; CHECK: declare float @nearbyintf(float) [[NOFREE]] +; CHECK: declare float @nearbyintf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @nearbyintf(float) -; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @nearbyintl(x86_fp80) -; CHECK: declare noundef i32 @open(i8* nocapture noundef readonly, i32 noundef, ...) [[NOFREE]] +; CHECK: declare noundef i32 @open(i8* nocapture noundef readonly, i32 noundef, ...) [[NOFREE:#[0-9]+]] declare i32 @open(i8*, i32, ...) ; CHECK-LINUX: declare noundef i32 @open64(i8* nocapture noundef readonly, i32 noundef, ...) [[NOFREE]] @@ -687,13 +691,13 @@ ; CHECK: declare i32 @posix_memalign(i8**, i64, i64) [[NOFREE]] declare i32 @posix_memalign(i8**, i64, i64) -; CHECK: declare double @pow(double, double) [[NOFREE]] +; CHECK: declare double @pow(double, double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @pow(double, double) -; CHECK: declare float @powf(float, float) [[NOFREE]] +; CHECK: declare float @powf(float, float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @powf(float, float) -; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @powl(x86_fp80, x86_fp80) ; CHECK: declare noundef i64 @pread(i32 noundef, i8* nocapture noundef, i64 noundef, i64 noundef) [[NOFREE]] @@ -744,25 +748,25 @@ ; CHECK: declare void @rewind(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] declare void @rewind(%opaque*) -; CHECK: declare double @rint(double) [[NOFREE]] +; CHECK: declare double @rint(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @rint(double) -; CHECK: declare float @rintf(float) [[NOFREE]] +; CHECK: declare float @rintf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @rintf(float) -; CHECK: declare x86_fp80 @rintl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @rintl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] 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]] +; CHECK: declare double @round(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @round(double) -; CHECK: declare float @roundf(float) [[NOFREE]] +; CHECK: declare float @roundf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @roundf(float) -; CHECK: declare x86_fp80 @roundl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @roundl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @roundl(x86_fp80) ; CHECK: declare noundef i32 @scanf(i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]] @@ -771,28 +775,28 @@ ; CHECK: declare void @setbuf(%opaque* nocapture noundef, i8* noundef) [[NOFREE_NOUNWIND]] declare void @setbuf(%opaque*, i8*) -; CHECK: declare noundef i32 @setitimer(i32 noundef, %opaque* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND]] +; CHECK: declare noundef i32 @setitimer(i32 noundef, %opaque* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND_WILLRETURN]] 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]] +; CHECK: declare double @sin(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @sin(double) -; CHECK: declare float @sinf(float) [[NOFREE]] +; CHECK: declare float @sinf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @sinf(float) -; CHECK: declare double @sinh(double) [[NOFREE]] +; CHECK: declare double @sinh(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @sinh(double) -; CHECK: declare float @sinhf(float) [[NOFREE]] +; CHECK: declare float @sinhf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @sinhf(float) -; CHECK: declare x86_fp80 @sinhl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @sinhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @sinhl(x86_fp80) -; CHECK: declare x86_fp80 @sinl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @sinl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @sinl(x86_fp80) ; CHECK: declare noundef i32 @snprintf(i8* noalias nocapture noundef writeonly, i64 noundef, i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]] @@ -801,13 +805,13 @@ ; 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]] +; CHECK: declare double @sqrt(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @sqrt(double) -; CHECK: declare float @sqrtf(float) [[NOFREE]] +; CHECK: declare float @sqrtf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @sqrtf(float) -; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @sqrtl(x86_fp80) ; CHECK: declare noundef i32 @sscanf(i8* nocapture noundef readonly, i8* nocapture noundef readonly, ...) [[NOFREE_NOUNWIND]] @@ -831,7 +835,7 @@ ; CHECK: declare i8* @stpncpy(i8* noalias writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]] declare i8* @stpncpy(i8*, i8*, i64) -; CHECK: declare i32 @strcasecmp(i8* nocapture, i8* nocapture) [[NOFREE_NOUNWIND_READONLY]] +; CHECK: declare i32 @strcasecmp(i8* nocapture, i8* nocapture) [[NOFREE_NOUNWIND_READONLY_WILLRETURN:#[0-9]+]] declare i32 @strcasecmp(i8*, i8*) ; CHECK: declare i8* @strcat(i8* noalias returned writeonly, i8* noalias nocapture readonly) [[ARGMEMONLY_NOFREE_NOUNWIND]] @@ -843,7 +847,7 @@ ; CHECK: declare i32 @strcmp(i8* nocapture, i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]] declare i32 @strcmp(i8*, i8*) -; CHECK: declare i32 @strcoll(i8* nocapture, i8* nocapture) [[NOFREE_NOUNWIND_READONLY]] +; CHECK: declare i32 @strcoll(i8* nocapture, i8* nocapture) [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] declare i32 @strcoll(i8*, i8*) ; CHECK: declare i8* @strcpy(i8* noalias returned writeonly, i8* noalias nocapture readonly) [[ARGMEMONLY_NOFREE_NOUNWIND]] @@ -852,13 +856,13 @@ ; CHECK: declare i64 @strcspn(i8* nocapture, i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]] declare i64 @strcspn(i8*, i8*) -; CHECK: declare noalias i8* @strdup(i8* nocapture readonly) [[NOFREE_NOUNWIND]] +; CHECK: declare noalias i8* @strdup(i8* nocapture readonly) [[NOFREE_NOUNWIND_WILLRETURN]] declare i8* @strdup(i8*) ; CHECK: declare i64 @strlen(i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]] declare i64 @strlen(i8*) -; CHECK: declare i32 @strncasecmp(i8* nocapture, i8* nocapture, i64) [[NOFREE_NOUNWIND_READONLY]] +; CHECK: declare i32 @strncasecmp(i8* nocapture, i8* nocapture, i64) [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] declare i32 @strncasecmp(i8*, i8*, i64) ; CHECK: declare i8* @strncat(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]] @@ -870,10 +874,10 @@ ; CHECK: declare i8* @strncpy(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]] declare i8* @strncpy(i8*, i8*, i64) -; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[NOFREE_NOUNWIND]] +; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i8* @strndup(i8*, i64) -; CHECK: declare i64 @strnlen(i8*, i64) [[NOFREE]] +; CHECK: declare i64 @strnlen(i8*, i64) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @strnlen(i8*, i64) ; CHECK: declare i8* @strpbrk(i8*, i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND:#[0-9]+]] @@ -888,55 +892,55 @@ ; CHECK: declare i8* @strstr(i8*, i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND]] declare i8* @strstr(i8*, i8*) -; CHECK: declare double @strtod(i8* readonly, i8** nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare double @strtod(i8* readonly, i8** nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @strtod(i8*, i8**) -; CHECK: declare float @strtof(i8* readonly, i8** nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare float @strtof(i8* readonly, i8** nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @strtof(i8*, i8**) -; CHECK: declare i8* @strtok(i8*, i8* nocapture readonly) [[NOFREE_NOUNWIND]] +; CHECK: declare i8* @strtok(i8*, i8* nocapture readonly) [[NOFREE_NOUNWIND_WILLRETURN]] declare i8* @strtok(i8*, i8*) -; CHECK: declare i8* @strtok_r(i8*, i8* nocapture readonly, i8**) [[NOFREE_NOUNWIND]] +; CHECK: declare i8* @strtok_r(i8*, i8* nocapture readonly, i8**) [[NOFREE_NOUNWIND_WILLRETURN]] declare i8* @strtok_r(i8*, i8*, i8**) -; CHECK: declare i64 @strtol(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND]] +; CHECK: declare i64 @strtol(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @strtol(i8*, i8**, i32) -; CHECK: declare x86_fp80 @strtold(i8* readonly, i8** nocapture) [[NOFREE_NOUNWIND]] +; CHECK: declare x86_fp80 @strtold(i8* readonly, i8** nocapture) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @strtold(i8*, i8**) -; CHECK: declare i64 @strtoll(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND]] +; CHECK: declare i64 @strtoll(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @strtoll(i8*, i8**, i32) -; CHECK: declare i64 @strtoul(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND]] +; CHECK: declare i64 @strtoul(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @strtoul(i8*, i8**, i32) -; CHECK: declare i64 @strtoull(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND]] +; CHECK: declare i64 @strtoull(i8* readonly, i8** nocapture, i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i64 @strtoull(i8*, i8**, i32) -; CHECK: declare i64 @strxfrm(i8* nocapture, i8* nocapture readonly, i64) [[NOFREE_NOUNWIND]] +; CHECK: declare i64 @strxfrm(i8* nocapture, i8* nocapture readonly, i64) [[NOFREE_NOUNWIND_WILLRETURN]] 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]] +; CHECK: declare double @tan(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @tan(double) -; CHECK: declare float @tanf(float) [[NOFREE]] +; CHECK: declare float @tanf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @tanf(float) -; CHECK: declare double @tanh(double) [[NOFREE]] +; CHECK: declare double @tanh(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @tanh(double) -; CHECK: declare float @tanhf(float) [[NOFREE]] +; CHECK: declare float @tanhf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @tanhf(float) -; CHECK: declare x86_fp80 @tanhl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @tanhl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @tanhl(x86_fp80) -; CHECK: declare x86_fp80 @tanl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @tanl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @tanl(x86_fp80) ; CHECK: declare noundef i64 @times(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] @@ -948,16 +952,16 @@ ; CHECK-LINUX: declare noalias noundef %opaque* @tmpfile64() [[NOFREE_NOUNWIND]] declare %opaque* @tmpfile64() -; CHECK: declare i32 @toascii(i32) [[NOFREE]] +; CHECK: declare i32 @toascii(i32) [[NOFREE_NOUNWIND_WILLRETURN]] declare i32 @toascii(i32) -; CHECK: declare double @trunc(double) [[NOFREE]] +; CHECK: declare double @trunc(double) [[NOFREE_NOUNWIND_WILLRETURN]] declare double @trunc(double) -; CHECK: declare float @truncf(float) [[NOFREE]] +; CHECK: declare float @truncf(float) [[NOFREE_NOUNWIND_WILLRETURN]] declare float @truncf(float) -; CHECK: declare x86_fp80 @truncl(x86_fp80) [[NOFREE]] +; CHECK: declare x86_fp80 @truncl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]] declare x86_fp80 @truncl(x86_fp80) ; CHECK: declare noundef i32 @uname(%opaque* nocapture noundef) [[NOFREE_NOUNWIND]] @@ -1010,9 +1014,12 @@ ; CHECK-DARWIN: declare void @memset_pattern16(i8* nocapture writeonly, i8* nocapture readonly, i64) [[ARGMEMONLY_NOFREE:#[0-9]+]] declare void @memset_pattern16(i8*, i8*, i64) -; CHECK: attributes [[NOFREE]] = { nofree } -; CHECK: attributes [[NOFREE_NOUNWIND]] = { nofree nounwind } -; CHECK: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind readonly } +; CHECK-DAG: attributes [[NOFREE_WILLRETURN]] = { nofree willreturn } +; CHECK-DAG: attributes [[NOFREE]] = { nofree } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { nofree nounwind willreturn } +; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { argmemonly nofree nounwind willreturn } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind readonly } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { nofree nounwind readonly willreturn } ; CHECK-DAG-UNKNOWN: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { argmemonly nofree nounwind } ; CHECK-DAG-UNKNOWN: attributes [[NOUNWIND]] = { nounwind } diff --git a/llvm/test/Transforms/LICM/strlen.ll b/llvm/test/Transforms/LICM/strlen.ll --- a/llvm/test/Transforms/LICM/strlen.ll +++ b/llvm/test/Transforms/LICM/strlen.ll @@ -13,7 +13,7 @@ } ; CHECK: declare i64 @strlen(i8* nocapture) #0 -; CHECK: attributes #0 = { argmemonly nofree nounwind readonly } +; CHECK: attributes #0 = { argmemonly nofree nounwind readonly willreturn } declare i64 @strlen(i8*)