diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -235,6 +235,10 @@ return strchr(getRecord(ID).Attributes, 'e') != nullptr; } + bool isConstWithoutExceptions(unsigned ID, bool NoExceptions) const { + return NoExceptions || strchr(getRecord(ID).Attributes, 'g') != nullptr; + } + const char *getRequiredFeatures(unsigned ID) const { return getRecord(ID).Features; } diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -98,6 +98,7 @@ // in that it accepts its arguments as a va_list rather than // through an ellipsis // e -> const, but only when -fno-math-errno +// g -> only const when FP exceptions are ignored // j -> returns_twice (like setjmp) // u -> arguments are not evaluated for their side-effects // V:N: -> requires vectors of at least N bits to be legal @@ -179,30 +180,30 @@ BUILTIN(__builtin_powf128, "LLdLLdLLd", "Fne") // Standard unary libc/libm functions with double/float/long double variants: -BUILTIN(__builtin_acos , "dd" , "Fne") -BUILTIN(__builtin_acosf, "ff" , "Fne") -BUILTIN(__builtin_acosl, "LdLd", "Fne") -BUILTIN(__builtin_acosf128, "LLdLLd", "Fne") -BUILTIN(__builtin_acosh , "dd" , "Fne") -BUILTIN(__builtin_acoshf, "ff" , "Fne") -BUILTIN(__builtin_acoshl, "LdLd", "Fne") -BUILTIN(__builtin_acoshf128, "LLdLLd", "Fne") -BUILTIN(__builtin_asin , "dd" , "Fne") -BUILTIN(__builtin_asinf, "ff" , "Fne") -BUILTIN(__builtin_asinl, "LdLd", "Fne") -BUILTIN(__builtin_asinf128, "LLdLLd", "Fne") -BUILTIN(__builtin_asinh , "dd" , "Fne") -BUILTIN(__builtin_asinhf, "ff" , "Fne") -BUILTIN(__builtin_asinhl, "LdLd", "Fne") -BUILTIN(__builtin_asinhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_atan , "dd" , "Fne") -BUILTIN(__builtin_atanf, "ff" , "Fne") -BUILTIN(__builtin_atanl, "LdLd", "Fne") -BUILTIN(__builtin_atanf128, "LLdLLd", "Fne") -BUILTIN(__builtin_atanh , "dd", "Fne") -BUILTIN(__builtin_atanhf, "ff", "Fne") -BUILTIN(__builtin_atanhl, "LdLd", "Fne") -BUILTIN(__builtin_atanhf128, "LLdLLd", "Fne") +BUILTIN(__builtin_acos , "dd" , "Fneg") +BUILTIN(__builtin_acosf, "ff" , "Fneg") +BUILTIN(__builtin_acosl, "LdLd", "Fneg") +BUILTIN(__builtin_acosf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_acosh , "dd" , "Fneg") +BUILTIN(__builtin_acoshf, "ff" , "Fneg") +BUILTIN(__builtin_acoshl, "LdLd", "Fneg") +BUILTIN(__builtin_acoshf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_asin , "dd" , "Fneg") +BUILTIN(__builtin_asinf, "ff" , "Fneg") +BUILTIN(__builtin_asinl, "LdLd", "Fneg") +BUILTIN(__builtin_asinf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_asinh , "dd" , "Fneg") +BUILTIN(__builtin_asinhf, "ff" , "Fneg") +BUILTIN(__builtin_asinhl, "LdLd", "Fneg") +BUILTIN(__builtin_asinhf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_atan , "dd" , "Fneg") +BUILTIN(__builtin_atanf, "ff" , "Fneg") +BUILTIN(__builtin_atanl, "LdLd", "Fneg") +BUILTIN(__builtin_atanf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_atanh , "dd", "Fneg") +BUILTIN(__builtin_atanhf, "ff", "Fneg") +BUILTIN(__builtin_atanhl, "LdLd", "Fneg") +BUILTIN(__builtin_atanhf128, "LLdLLd", "Fneg") BUILTIN(__builtin_cbrt , "dd", "Fnc") BUILTIN(__builtin_cbrtf, "ff", "Fnc") BUILTIN(__builtin_cbrtl, "LdLd", "Fnc") @@ -212,15 +213,15 @@ BUILTIN(__builtin_ceilf16, "hh" , "Fnc") BUILTIN(__builtin_ceill, "LdLd", "Fnc") BUILTIN(__builtin_ceilf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_cos , "dd" , "Fne") -BUILTIN(__builtin_cosf, "ff" , "Fne") -BUILTIN(__builtin_cosf16, "hh" , "Fne") -BUILTIN(__builtin_cosh , "dd" , "Fne") -BUILTIN(__builtin_coshf, "ff" , "Fne") -BUILTIN(__builtin_coshl, "LdLd", "Fne") -BUILTIN(__builtin_coshf128, "LLdLLd", "Fne") -BUILTIN(__builtin_cosl, "LdLd", "Fne") -BUILTIN(__builtin_cosf128, "LLdLLd" , "Fne") +BUILTIN(__builtin_cos , "dd" , "Fneg") +BUILTIN(__builtin_cosf, "ff" , "Fneg") +BUILTIN(__builtin_cosf16, "hh" , "Fneg") +BUILTIN(__builtin_cosh , "dd" , "Fneg") +BUILTIN(__builtin_coshf, "ff" , "Fneg") +BUILTIN(__builtin_coshl, "LdLd", "Fneg") +BUILTIN(__builtin_coshf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_cosl, "LdLd", "Fneg") +BUILTIN(__builtin_cosf128, "LLdLLd" , "Fneg") BUILTIN(__builtin_erf , "dd", "Fne") BUILTIN(__builtin_erff, "ff", "Fne") BUILTIN(__builtin_erfl, "LdLd", "Fne") @@ -229,20 +230,20 @@ BUILTIN(__builtin_erfcf, "ff", "Fne") BUILTIN(__builtin_erfcl, "LdLd", "Fne") BUILTIN(__builtin_erfcf128, "LLdLLd", "Fne") -BUILTIN(__builtin_exp , "dd" , "Fne") -BUILTIN(__builtin_expf, "ff" , "Fne") -BUILTIN(__builtin_expf16, "hh" , "Fne") -BUILTIN(__builtin_expl, "LdLd", "Fne") -BUILTIN(__builtin_expf128, "LLdLLd", "Fne") -BUILTIN(__builtin_exp2 , "dd" , "Fne") -BUILTIN(__builtin_exp2f, "ff" , "Fne") -BUILTIN(__builtin_exp2f16, "hh" , "Fne") -BUILTIN(__builtin_exp2l, "LdLd", "Fne") -BUILTIN(__builtin_exp2f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_expm1 , "dd", "Fne") -BUILTIN(__builtin_expm1f, "ff", "Fne") -BUILTIN(__builtin_expm1l, "LdLd", "Fne") -BUILTIN(__builtin_expm1f128, "LLdLLd", "Fne") +BUILTIN(__builtin_exp , "dd" , "Fneg") +BUILTIN(__builtin_expf, "ff" , "Fneg") +BUILTIN(__builtin_expf16, "hh" , "Fneg") +BUILTIN(__builtin_expl, "LdLd", "Fneg") +BUILTIN(__builtin_expf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_exp2 , "dd" , "Fneg") +BUILTIN(__builtin_exp2f, "ff" , "Fneg") +BUILTIN(__builtin_exp2f16, "hh" , "Fneg") +BUILTIN(__builtin_exp2l, "LdLd", "Fneg") +BUILTIN(__builtin_exp2f128, "LLdLLd" , "Fneg") +BUILTIN(__builtin_expm1 , "dd", "Fneg") +BUILTIN(__builtin_expm1f, "ff", "Fneg") +BUILTIN(__builtin_expm1l, "LdLd", "Fneg") +BUILTIN(__builtin_expm1f128, "LLdLLd", "Fneg") BUILTIN(__builtin_fdim, "ddd", "Fne") BUILTIN(__builtin_fdimf, "fff", "Fne") BUILTIN(__builtin_fdiml, "LdLdLd", "Fne") @@ -252,11 +253,11 @@ BUILTIN(__builtin_floorf16, "hh" , "Fnc") BUILTIN(__builtin_floorl, "LdLd", "Fnc") BUILTIN(__builtin_floorf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_fma, "dddd", "Fne") -BUILTIN(__builtin_fmaf, "ffff", "Fne") -BUILTIN(__builtin_fmaf16, "hhhh", "Fne") -BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne") -BUILTIN(__builtin_fmaf128, "LLdLLdLLdLLd", "Fne") +BUILTIN(__builtin_fma, "dddd", "Fneg") +BUILTIN(__builtin_fmaf, "ffff", "Fneg") +BUILTIN(__builtin_fmaf16, "hhhh", "Fneg") +BUILTIN(__builtin_fmal, "LdLdLdLd", "Fneg") +BUILTIN(__builtin_fmaf128, "LLdLLdLLdLLd", "Fneg") BUILTIN(__builtin_fmax, "ddd", "Fnc") BUILTIN(__builtin_fmaxf, "fff", "Fnc") BUILTIN(__builtin_fmaxf16, "hhh", "Fnc") @@ -271,83 +272,83 @@ BUILTIN(__builtin_hypotf, "fff" , "Fne") BUILTIN(__builtin_hypotl, "LdLdLd", "Fne") BUILTIN(__builtin_hypotf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_ilogb , "id", "Fne") -BUILTIN(__builtin_ilogbf, "if", "Fne") -BUILTIN(__builtin_ilogbl, "iLd", "Fne") -BUILTIN(__builtin_ilogbf128, "iLLd", "Fne") -BUILTIN(__builtin_lgamma , "dd", "Fn") -BUILTIN(__builtin_lgammaf, "ff", "Fn") -BUILTIN(__builtin_lgammal, "LdLd", "Fn") -BUILTIN(__builtin_lgammaf128, "LLdLLd", "Fn") -BUILTIN(__builtin_llrint, "LLid", "Fne") -BUILTIN(__builtin_llrintf, "LLif", "Fne") -BUILTIN(__builtin_llrintl, "LLiLd", "Fne") -BUILTIN(__builtin_llrintf128, "LLiLLd", "Fne") -BUILTIN(__builtin_llround , "LLid", "Fne") -BUILTIN(__builtin_llroundf, "LLif", "Fne") -BUILTIN(__builtin_llroundl, "LLiLd", "Fne") -BUILTIN(__builtin_llroundf128, "LLiLLd", "Fne") -BUILTIN(__builtin_log , "dd" , "Fne") -BUILTIN(__builtin_log10 , "dd" , "Fne") -BUILTIN(__builtin_log10f, "ff" , "Fne") -BUILTIN(__builtin_log10f16, "hh" , "Fne") -BUILTIN(__builtin_log10l, "LdLd", "Fne") -BUILTIN(__builtin_log10f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_log1p , "dd" , "Fne") -BUILTIN(__builtin_log1pf, "ff" , "Fne") -BUILTIN(__builtin_log1pl, "LdLd", "Fne") -BUILTIN(__builtin_log1pf128, "LLdLLd", "Fne") -BUILTIN(__builtin_log2, "dd" , "Fne") -BUILTIN(__builtin_log2f, "ff" , "Fne") -BUILTIN(__builtin_log2f16, "hh" , "Fne") -BUILTIN(__builtin_log2l, "LdLd" , "Fne") -BUILTIN(__builtin_log2f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_logb , "dd", "Fne") -BUILTIN(__builtin_logbf, "ff", "Fne") -BUILTIN(__builtin_logbl, "LdLd", "Fne") -BUILTIN(__builtin_logbf128, "LLdLLd", "Fne") -BUILTIN(__builtin_logf, "ff" , "Fne") -BUILTIN(__builtin_logf16, "hh" , "Fne") -BUILTIN(__builtin_logl, "LdLd", "Fne") -BUILTIN(__builtin_logf128, "LLdLLd", "Fne") -BUILTIN(__builtin_lrint , "Lid", "Fne") -BUILTIN(__builtin_lrintf, "Lif", "Fne") -BUILTIN(__builtin_lrintl, "LiLd", "Fne") -BUILTIN(__builtin_lrintf128, "LiLLd", "Fne") -BUILTIN(__builtin_lround , "Lid", "Fne") -BUILTIN(__builtin_lroundf, "Lif", "Fne") -BUILTIN(__builtin_lroundl, "LiLd", "Fne") -BUILTIN(__builtin_lroundf128, "LiLLd", "Fne") +BUILTIN(__builtin_ilogb , "id", "Fneg") +BUILTIN(__builtin_ilogbf, "if", "Fneg") +BUILTIN(__builtin_ilogbl, "iLd", "Fneg") +BUILTIN(__builtin_ilogbf128, "iLLd", "Fneg") +BUILTIN(__builtin_lgamma , "dd", "Fng") +BUILTIN(__builtin_lgammaf, "ff", "Fng") +BUILTIN(__builtin_lgammal, "LdLd", "Fng") +BUILTIN(__builtin_lgammaf128, "LLdLLd", "Fng") +BUILTIN(__builtin_llrint, "LLid", "Fneg") +BUILTIN(__builtin_llrintf, "LLif", "Fneg") +BUILTIN(__builtin_llrintl, "LLiLd", "Fneg") +BUILTIN(__builtin_llrintf128, "LLiLLd", "Fneg") +BUILTIN(__builtin_llround , "LLid", "Fneg") +BUILTIN(__builtin_llroundf, "LLif", "Fneg") +BUILTIN(__builtin_llroundl, "LLiLd", "Fneg") +BUILTIN(__builtin_llroundf128, "LLiLLd", "Fneg") +BUILTIN(__builtin_log , "dd" , "Fneg") +BUILTIN(__builtin_log10 , "dd" , "Fneg") +BUILTIN(__builtin_log10f, "ff" , "Fneg") +BUILTIN(__builtin_log10f16, "hh" , "Fneg") +BUILTIN(__builtin_log10l, "LdLd", "Fneg") +BUILTIN(__builtin_log10f128, "LLdLLd" , "Fneg") +BUILTIN(__builtin_log1p , "dd" , "Fneg") +BUILTIN(__builtin_log1pf, "ff" , "Fneg") +BUILTIN(__builtin_log1pl, "LdLd", "Fneg") +BUILTIN(__builtin_log1pf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_log2, "dd" , "Fneg") +BUILTIN(__builtin_log2f, "ff" , "Fneg") +BUILTIN(__builtin_log2f16, "hh" , "Fneg") +BUILTIN(__builtin_log2l, "LdLd" , "Fneg") +BUILTIN(__builtin_log2f128, "LLdLLd" , "Fneg") +BUILTIN(__builtin_logb , "dd", "Fneg") +BUILTIN(__builtin_logbf, "ff", "Fneg") +BUILTIN(__builtin_logbl, "LdLd", "Fneg") +BUILTIN(__builtin_logbf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_logf, "ff" , "Fneg") +BUILTIN(__builtin_logf16, "hh" , "Fneg") +BUILTIN(__builtin_logl, "LdLd", "Fneg") +BUILTIN(__builtin_logf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_lrint , "Lid", "Fneg") +BUILTIN(__builtin_lrintf, "Lif", "Fneg") +BUILTIN(__builtin_lrintl, "LiLd", "Fneg") +BUILTIN(__builtin_lrintf128, "LiLLd", "Fneg") +BUILTIN(__builtin_lround , "Lid", "Fneg") +BUILTIN(__builtin_lroundf, "Lif", "Fneg") +BUILTIN(__builtin_lroundl, "LiLd", "Fneg") +BUILTIN(__builtin_lroundf128, "LiLLd", "Fneg") BUILTIN(__builtin_nearbyint , "dd", "Fnc") BUILTIN(__builtin_nearbyintf, "ff", "Fnc") BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc") BUILTIN(__builtin_nearbyintf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_nextafter , "ddd", "Fne") -BUILTIN(__builtin_nextafterf, "fff", "Fne") -BUILTIN(__builtin_nextafterl, "LdLdLd", "Fne") -BUILTIN(__builtin_nextafterf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_nexttoward , "ddLd", "Fne") -BUILTIN(__builtin_nexttowardf, "ffLd", "Fne") -BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fne") -BUILTIN(__builtin_nexttowardf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_remainder , "ddd", "Fne") -BUILTIN(__builtin_remainderf, "fff", "Fne") -BUILTIN(__builtin_remainderl, "LdLdLd", "Fne") -BUILTIN(__builtin_remainderf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_remquo , "dddi*", "Fn") -BUILTIN(__builtin_remquof, "fffi*", "Fn") -BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") -BUILTIN(__builtin_remquof128, "LLdLLdLLdi*", "Fn") -BUILTIN(__builtin_rint , "dd", "Fnc") -BUILTIN(__builtin_rintf, "ff", "Fnc") -BUILTIN(__builtin_rintf16, "hh", "Fnc") -BUILTIN(__builtin_rintl, "LdLd", "Fnc") -BUILTIN(__builtin_rintf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_round, "dd" , "Fnc") -BUILTIN(__builtin_roundf, "ff" , "Fnc") -BUILTIN(__builtin_roundf16, "hh" , "Fnc") -BUILTIN(__builtin_roundl, "LdLd" , "Fnc") -BUILTIN(__builtin_roundf128, "LLdLLd" , "Fnc") +BUILTIN(__builtin_nextafter , "ddd", "Fneg") +BUILTIN(__builtin_nextafterf, "fff", "Fneg") +BUILTIN(__builtin_nextafterl, "LdLdLd", "Fneg") +BUILTIN(__builtin_nextafterf128, "LLdLLdLLd", "Fneg") +BUILTIN(__builtin_nexttoward , "ddLd", "Fneg") +BUILTIN(__builtin_nexttowardf, "ffLd", "Fneg") +BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fneg") +BUILTIN(__builtin_nexttowardf128, "LLdLLdLLd", "Fneg") +BUILTIN(__builtin_remainder , "ddd", "Fneg") +BUILTIN(__builtin_remainderf, "fff", "Fneg") +BUILTIN(__builtin_remainderl, "LdLdLd", "Fneg") +BUILTIN(__builtin_remainderf128, "LLdLLdLLd", "Fneg") +BUILTIN(__builtin_remquo , "dddi*", "Fng") +BUILTIN(__builtin_remquof, "fffi*", "Fng") +BUILTIN(__builtin_remquol, "LdLdLdi*", "Fng") +BUILTIN(__builtin_remquof128, "LLdLLdLLdi*", "Fng") +BUILTIN(__builtin_rint , "dd", "Fncg") +BUILTIN(__builtin_rintf, "ff", "Fncg") +BUILTIN(__builtin_rintf16, "hh", "Fncg") +BUILTIN(__builtin_rintl, "LdLd", "Fncg") +BUILTIN(__builtin_rintf128, "LLdLLd", "Fncg") +BUILTIN(__builtin_round, "dd" , "Fncg") +BUILTIN(__builtin_roundf, "ff" , "Fncg") +BUILTIN(__builtin_roundf16, "hh" , "Fncg") +BUILTIN(__builtin_roundl, "LdLd" , "Fncg") +BUILTIN(__builtin_roundf128, "LLdLLd" , "Fncg") BUILTIN(__builtin_scalbln , "ddLi", "Fne") BUILTIN(__builtin_scalblnf, "ffLi", "Fne") BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne") @@ -356,32 +357,32 @@ BUILTIN(__builtin_scalbnf, "ffi", "Fne") BUILTIN(__builtin_scalbnl, "LdLdi", "Fne") BUILTIN(__builtin_scalbnf128, "LLdLLdi", "Fne") -BUILTIN(__builtin_sin , "dd" , "Fne") -BUILTIN(__builtin_sinf, "ff" , "Fne") -BUILTIN(__builtin_sinf16, "hh" , "Fne") -BUILTIN(__builtin_sinh , "dd" , "Fne") -BUILTIN(__builtin_sinhf, "ff" , "Fne") -BUILTIN(__builtin_sinhl, "LdLd", "Fne") -BUILTIN(__builtin_sinhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_sinl, "LdLd", "Fne") -BUILTIN(__builtin_sinf128, "LLdLLd" , "Fne") -BUILTIN(__builtin_sqrt , "dd" , "Fne") -BUILTIN(__builtin_sqrtf, "ff" , "Fne") -BUILTIN(__builtin_sqrtf16, "hh" , "Fne") -BUILTIN(__builtin_sqrtl, "LdLd", "Fne") -BUILTIN(__builtin_sqrtf128, "LLdLLd", "Fne") -BUILTIN(__builtin_tan , "dd" , "Fne") -BUILTIN(__builtin_tanf, "ff" , "Fne") -BUILTIN(__builtin_tanh , "dd" , "Fne") -BUILTIN(__builtin_tanhf, "ff" , "Fne") -BUILTIN(__builtin_tanhl, "LdLd", "Fne") -BUILTIN(__builtin_tanhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_tanl, "LdLd", "Fne") -BUILTIN(__builtin_tanf128, "LLdLLd" , "Fne") -BUILTIN(__builtin_tgamma , "dd", "Fne") -BUILTIN(__builtin_tgammaf, "ff", "Fne") -BUILTIN(__builtin_tgammal, "LdLd", "Fne") -BUILTIN(__builtin_tgammaf128, "LLdLLd", "Fne") +BUILTIN(__builtin_sin , "dd" , "Fneg") +BUILTIN(__builtin_sinf, "ff" , "Fneg") +BUILTIN(__builtin_sinf16, "hh" , "Fneg") +BUILTIN(__builtin_sinh , "dd" , "Fneg") +BUILTIN(__builtin_sinhf, "ff" , "Fneg") +BUILTIN(__builtin_sinhl, "LdLd", "Fneg") +BUILTIN(__builtin_sinhf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_sinl, "LdLd", "Fneg") +BUILTIN(__builtin_sinf128, "LLdLLd" , "Fneg") +BUILTIN(__builtin_sqrt , "dd" , "Fneg") +BUILTIN(__builtin_sqrtf, "ff" , "Fneg") +BUILTIN(__builtin_sqrtf16, "hh" , "Fneg") +BUILTIN(__builtin_sqrtl, "LdLd", "Fneg") +BUILTIN(__builtin_sqrtf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_tan , "dd" , "Fneg") +BUILTIN(__builtin_tanf, "ff" , "Fneg") +BUILTIN(__builtin_tanh , "dd" , "Fneg") +BUILTIN(__builtin_tanhf, "ff" , "Fneg") +BUILTIN(__builtin_tanhl, "LdLd", "Fneg") +BUILTIN(__builtin_tanhf128, "LLdLLd", "Fneg") +BUILTIN(__builtin_tanl, "LdLd", "Fneg") +BUILTIN(__builtin_tanf128, "LLdLLd" , "Fneg") +BUILTIN(__builtin_tgamma , "dd", "Fneg") +BUILTIN(__builtin_tgammaf, "ff", "Fneg") +BUILTIN(__builtin_tgammal, "LdLd", "Fneg") +BUILTIN(__builtin_tgammaf128, "LLdLLd", "Fneg") BUILTIN(__builtin_trunc , "dd", "Fnc") BUILTIN(__builtin_truncf, "ff", "Fnc") BUILTIN(__builtin_truncl, "LdLd", "Fnc") diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15532,8 +15532,11 @@ // Mark const if we don't care about errno and that is the only thing // preventing the function from being const. This allows IRgen to use LLVM // intrinsics for such functions. + bool NoExceptions = + getLangOpts().getDefaultExceptionMode() == LangOptions::FPE_Ignore; if (!getLangOpts().MathErrno && !FD->hasAttr() && - Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) + Context.BuiltinInfo.isConstWithoutErrno(BuiltinID) && + Context.BuiltinInfo.isConstWithoutExceptions(BuiltinID, NoExceptions)) FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); // We make "fma" on GNU or Windows const because we know it does not set diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -10,10 +10,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { f = __builtin_fmod(f,f); f = __builtin_fmodf(f,f); f = __builtin_fmodl(f,f); f = __builtin_fmodf128(f,f); -// CHECK: call double @llvm.experimental.constrained.frem.f64(double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.frem.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.frem.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call double @fmod( +// CHECK: call float @fmodf( +// CHECK: call x86_fp80 @fmodl( +// CHECK: call fp128 @fmodf128( __builtin_pow(f,f); __builtin_powf(f,f); __builtin_powl(f,f); __builtin_powf128(f,f); diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c --- a/clang/test/CodeGen/math-libcalls.c +++ b/clang/test/CodeGen/math-libcalls.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm %s | FileCheck %s --check-prefix=NO__ERRNO // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO +// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm -ffp-exception-behavior=maytrap %s | FileCheck %s --check-prefix=HAS_MAYTRAP // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-unknown-gnu -Wno-implicit-function-declaration -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-windows-msvc -Wno-implicit-function-declaration -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN @@ -8,66 +9,87 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { f = fmod(f,f); f = fmodf(f,f); f = fmodl(f,f); -// NO__ERRNO: frem double -// NO__ERRNO: frem float -// NO__ERRNO: frem x86_fp80 -// HAS_ERRNO: declare double @fmod(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]] -// HAS_ERRNO: declare float @fmodf(float noundef, float noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]] + // NO__ERRNO: frem double + // NO__ERRNO: frem float + // NO__ERRNO: frem x86_fp80 + // HAS_ERRNO: declare double @fmod(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]] + // HAS_ERRNO: declare float @fmodf(float noundef, float noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare double @fmod(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]] + // HAS_MAYTRAP: declare float @fmodf(float noundef, float noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare x86_fp80 @fmodl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]] atan2(f,f); atan2f(f,f) ; atan2l(f, f); -// NO__ERRNO: declare double @atan2(double noundef, double noundef) [[READNONE:#[0-9]+]] -// NO__ERRNO: declare float @atan2f(float noundef, float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]] -// HAS_ERRNO: declare double @atan2(double noundef, double noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]] + // NO__ERRNO: declare double @atan2(double noundef, double noundef) [[READNONE:#[0-9]+]] + // NO__ERRNO: declare float @atan2f(float noundef, float noundef) [[READNONE]] + // NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]] + // HAS_ERRNO: declare double @atan2(double noundef, double noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare double @atan2(double noundef, double noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]] copysign(f,f); copysignf(f,f);copysignl(f,f); -// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] -// NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] -// HAS_ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] -// HAS_ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] -// HAS_ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + // NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] + // NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] + // NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + // HAS_ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] + // HAS_ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] + // HAS_ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + // HAS_MAYTRAP: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] + // HAS_MAYTRAP: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] + // HAS_MAYTRAP: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] fabs(f); fabsf(f); fabsl(f); -// NO__ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] -// HAS_ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] -// HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] -// HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] + // NO__ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] + // NO__ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] + // NO__ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] + // HAS_ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] + // HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] + // HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] + // HAS_MAYTRAP: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] + // HAS_MAYTRAP: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] + // HAS_MAYTRAP: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] frexp(f,i); frexpf(f,i); frexpl(f,i); -// NO__ERRNO: declare double @frexp(double noundef, i32* noundef) [[NOT_READNONE:#[0-9]+]] -// NO__ERRNO: declare float @frexpf(float noundef, i32* noundef) [[NOT_READNONE]] -// NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, i32* noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare double @frexp(double noundef, i32* noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare float @frexpf(float noundef, i32* noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, i32* noundef) [[NOT_READNONE]] + // NO__ERRNO: declare double @frexp(double noundef, i32* noundef) [[NOT_READNONE:#[0-9]+]] + // NO__ERRNO: declare float @frexpf(float noundef, i32* noundef) [[NOT_READNONE]] + // NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, i32* noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare double @frexp(double noundef, i32* noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare float @frexpf(float noundef, i32* noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, i32* noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare double @frexp(double noundef, i32* noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare float @frexpf(float noundef, i32* noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare x86_fp80 @frexpl(x86_fp80 noundef, i32* noundef) [[NOT_READNONE]] ldexp(f,f); ldexpf(f,f); ldexpl(f,f); -// NO__ERRNO: declare double @ldexp(double noundef, i32 noundef) [[READNONE]] -// NO__ERRNO: declare float @ldexpf(float noundef, i32 noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[READNONE]] -// HAS_ERRNO: declare double @ldexp(double noundef, i32 noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare float @ldexpf(float noundef, i32 noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[NOT_READNONE]] + // NO__ERRNO: declare double @ldexp(double noundef, i32 noundef) [[READNONE]] + // NO__ERRNO: declare float @ldexpf(float noundef, i32 noundef) [[READNONE]] + // NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[READNONE]] + // HAS_ERRNO: declare double @ldexp(double noundef, i32 noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare float @ldexpf(float noundef, i32 noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare double @ldexp(double noundef, i32 noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare float @ldexpf(float noundef, i32 noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[NOT_READNONE]] modf(f,d); modff(f,fp); modfl(f,l); -// NO__ERRNO: declare double @modf(double noundef, double* noundef) [[NOT_READNONE]] -// NO__ERRNO: declare float @modff(float noundef, float* noundef) [[NOT_READNONE]] -// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, x86_fp80* noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare double @modf(double noundef, double* noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare float @modff(float noundef, float* noundef) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, x86_fp80* noundef) [[NOT_READNONE]] + // NO__ERRNO: declare double @modf(double noundef, double* noundef) [[NOT_READNONE]] + // NO__ERRNO: declare float @modff(float noundef, float* noundef) [[NOT_READNONE]] + // NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, x86_fp80* noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare double @modf(double noundef, double* noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare float @modff(float noundef, float* noundef) [[NOT_READNONE]] + // HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, x86_fp80* noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare double @modf(double noundef, double* noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare float @modff(float noundef, float* noundef) [[NOT_READNONE]] + // HAS_MAYTRAP: declare x86_fp80 @modfl(x86_fp80 noundef, x86_fp80* noundef) [[NOT_READNONE]] nan(c); nanf(c); nanl(c); @@ -542,5 +564,10 @@ // HAS_ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} } // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_MAYTRAP: attributes [[NOT_READNONE]] = { nounwind {{.*}} } +// HAS_MAYTRAP: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// HAS_MAYTRAPxx: attributes [[READONLY]] = { {{.*}}readonly{{.*}} } +// HAS_MAYTRAPxx: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } + // HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } // HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }