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

Reply via email to