spatel created this revision. Herald added a subscriber: mcrosier. These are 3 errno-related diffs raised in D39841.
1. Cube root We're going to dismiss POSIX language like this: "On successful completion, cbrt() returns the cube root of x. If x is NaN, cbrt() returns NaN and errno may be set to [EDOM]. " http://pubs.opengroup.org/onlinepubs/7908799/xsh/cbrt.html And favor an interpretation based on the C standard that says: "Functions with a NaN argument return a NaN result and raise no floating-point exception, except where stated otherwise." 2. Floating multiply-add The C standard is silent? http://pubs.opengroup.org/onlinepubs/9699919799/functions/fma.html - clearly says "...then errno shall be set..." but: https://linux.die.net/man/3/fma - "These functions do not set errno." Let's opt for the - hopefully common - implementation where errno is not set. Note that there's no test change because as noted in the earlier discussion, we're ignoring the const attr in CodeGenFunction::EmitBuiltinExpr(). I'll look at what needs fixing in that function next. 3. Complex This is came up specifically for 'carg', but I'm hoping we can use 1 justification for the whole lib. The POSIX docs all have language like this for complex calls: "No errors are defined." http://pubs.opengroup.org/onlinepubs/9699919799/functions/ccos.html The lack of errno handling is allowed by the inclusion of "optionally" in the C standard definitions of all of the complex ops? "csqrt(x + iNaN) returns NaN + iNaN and optionally raises the ‘‘invalid’’ floating-point exception, for finite x" https://reviews.llvm.org/D39611 Files: include/clang/Basic/Builtins.def test/CodeGen/builtin-errno.c test/CodeGen/libcalls-errno.c
Index: test/CodeGen/libcalls-errno.c =================================================================== --- test/CodeGen/libcalls-errno.c +++ test/CodeGen/libcalls-errno.c @@ -153,9 +153,9 @@ // NO__ERRNO: declare double @cbrt(double) [[READNONE]] // NO__ERRNO: declare float @cbrtf(float) [[READNONE]] // NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] -// HAS_ERRNO: declare double @cbrt(double) [[NOT_READNONE]] -// HAS_ERRNO: declare float @cbrtf(float) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare double @cbrt(double) [[READNONE]] +// HAS_ERRNO: declare float @cbrtf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] ceil(f); ceilf(f); ceill(f); Index: test/CodeGen/builtin-errno.c =================================================================== --- test/CodeGen/builtin-errno.c +++ test/CodeGen/builtin-errno.c @@ -198,9 +198,9 @@ // NO__ERRNO: declare double @cbrt(double) [[READNONE]] // NO__ERRNO: declare float @cbrtf(float) [[READNONE]] // NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] -// HAS_ERRNO: declare double @cbrt(double) [[NOT_READNONE]] -// HAS_ERRNO: declare float @cbrtf(float) [[NOT_READNONE]] -// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare double @cbrt(double) [[READNONE]] +// HAS_ERRNO: declare float @cbrtf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] __builtin_ceil(f); __builtin_ceilf(f); __builtin_ceill(f); Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -165,9 +165,11 @@ BUILTIN(__builtin_atanh , "dd", "Fne") BUILTIN(__builtin_atanhf, "ff", "Fne") BUILTIN(__builtin_atanhl, "LdLd", "Fne") -BUILTIN(__builtin_cbrt , "dd", "Fne") -BUILTIN(__builtin_cbrtf, "ff", "Fne") -BUILTIN(__builtin_cbrtl, "LdLd", "Fne") +// Disregard that 'cbrt' could set errno with a NaN input. The C standard says +// that NaN arguments generally do not raise FP exceptions. +BUILTIN(__builtin_cbrt , "dd", "Fnc") +BUILTIN(__builtin_cbrtf, "ff", "Fnc") +BUILTIN(__builtin_cbrtl, "LdLd", "Fnc") BUILTIN(__builtin_ceil , "dd" , "Fnc") BUILTIN(__builtin_ceilf, "ff" , "Fnc") BUILTIN(__builtin_ceill, "LdLd", "Fnc") @@ -198,9 +200,11 @@ BUILTIN(__builtin_floor , "dd" , "Fnc") BUILTIN(__builtin_floorf, "ff" , "Fnc") BUILTIN(__builtin_floorl, "LdLd", "Fnc") -BUILTIN(__builtin_fma, "dddd", "Fne") -BUILTIN(__builtin_fmaf, "ffff", "Fne") -BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne") +// Disregard that 'fma' could set errno. This is based on the assumption that no +// reasonable implementation would set errno and harm performance of a basic op. +BUILTIN(__builtin_fma, "dddd", "Fnc") +BUILTIN(__builtin_fmaf, "ffff", "Fnc") +BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc") BUILTIN(__builtin_fmax, "ddd", "Fnc") BUILTIN(__builtin_fmaxf, "fff", "Fnc") BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc") @@ -293,6 +297,8 @@ BUILTIN(__builtin_truncl, "LdLd", "Fnc") // C99 complex builtins +// All complex calls are marked const regardless of errno because exceptions are +// listed as optional in the C standard. POSIX says these do not have errors. BUILTIN(__builtin_cabs, "dXd", "Fnc") BUILTIN(__builtin_cabsf, "fXf", "Fnc") BUILTIN(__builtin_cabsl, "LdXLd", "Fnc") @@ -1040,9 +1046,11 @@ LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES) +// Disregard that 'cbrt' could set errno with a NaN input. The C standard says +// that NaN arguments generally do not raise FP exceptions. +LIBBUILTIN(cbrt, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(cbrtf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(cbrtl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES) @@ -1084,9 +1092,11 @@ LIBBUILTIN(floorf, "ff", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(floorl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fma, "dddd", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fmaf, "ffff", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fmal, "LdLdLdLd", "fne", "math.h", ALL_LANGUAGES) +// Disregard that fma could set errno. This is based on the assumption that no +// reasonable implementation would set errno and harm performance of a basic op. +LIBBUILTIN(fma, "dddd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaf, "ffff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmal, "LdLdLdLd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(fmax, "ddd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(fmaxf, "fff", "fnc", "math.h", ALL_LANGUAGES) @@ -1206,6 +1216,8 @@ LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) +// All complex calls are marked const regardless of errno because exceptions are +// listed as optional in the C standard. POSIX says these do not have errors. LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits