fhahn updated this revision to Diff 448628.
fhahn added a comment.


In D129231#3638946 <https://reviews.llvm.org/D129231#3638946>, @john.brawn 
wrote:

> Looking at the descriptions of maths functions in C99 (and I expect C11 will 
> be the same) it looks like there are three kinds:
>
> - Those that can report error by errno and floating-point exeption, and may 
> also raise the inexact exception
> - Those that don't set errno, but may raise the inexact exception
> - Those that neither set errno or raise an exception
>
> Looking at this patch and the attributes of the various function intrinsics 
> it looks like you have:
>
> - Marked "e": Can set errno, can't raise exception
> - Marked "eg": Can set errno and raise exception
> - Marked "cg": Can't set errno, can raise an exception
> - Marked "c": Can't set errno or raise an exception
>
> Given that the functions that set errno also raise exceptions I think it 
> would make sense to have the "e" attribute cover both errno and exceptions, 
> and have "g" just for those that can only raise exceptions. Also "cg" looks 
> like it's probably wrong and should be "g" (given that "c" means "always 
> const" and "g" means "const only when we don't have exceptions", and that's 
> also how "e" is used in that we don't have functions with "cg").

Thanks you very much for taking a look! I updated the patch to redefine "e" to 
mean const if no errno and no exceptions. Now the only markings are either "e" 
or "g". The functions originally marked "cg" were indeed a mistake.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129231/new/

https://reviews.llvm.org/D129231

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/Builtins.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CodeGen/math-libcalls.c

Index: clang/test/CodeGen/math-libcalls.c
===================================================================
--- clang/test/CodeGen/math-libcalls.c
+++ clang/test/CodeGen/math-libcalls.c
@@ -27,9 +27,9 @@
   // 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) [[READNONE:#[0-9]+]]
-  // HAS_MAYTRAP: declare float @atan2f(float noundef, float noundef) [[READNONE]]
-  // HAS_MAYTRAP: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
+  // HAS_MAYTRAP: declare double @atan2(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]]
+  // 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);
 
@@ -63,7 +63,7 @@
   // 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:#[0-9]+]]
+  // 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]]
 
@@ -75,9 +75,9 @@
   // 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) [[READNONE]]
-  // HAS_MAYTRAP: declare float @ldexpf(float noundef, i32 noundef) [[READNONE]]
-  // HAS_MAYTRAP: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[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);
 
@@ -125,9 +125,9 @@
 // HAS_ERRNO: declare double @acos(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @acosf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @acos(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @acosf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @acosl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @acos(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @acosf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @acosl(x86_fp80 noundef) [[NOT_READNONE]]
 
 
   acosh(f);      acoshf(f);     acoshl(f);
@@ -138,9 +138,9 @@
 // HAS_ERRNO: declare double @acosh(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @acoshf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @acoshl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @acosh(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @acoshf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @acoshl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @acosh(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @acoshf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @acoshl(x86_fp80 noundef) [[NOT_READNONE]]
 
   asin(f);       asinf(f);      asinl(f);
 
@@ -150,9 +150,9 @@
 // HAS_ERRNO: declare double @asin(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @asinf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @asin(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @asinf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @asinl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @asin(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @asinf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @asinl(x86_fp80 noundef) [[NOT_READNONE]]
 
   asinh(f);      asinhf(f);     asinhl(f);
 
@@ -162,9 +162,9 @@
 // HAS_ERRNO: declare double @asinh(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @asinhf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @asinhl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @asinh(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @asinhf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @asinhl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @asinh(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @asinhf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @asinhl(x86_fp80 noundef) [[NOT_READNONE]]
 
   atan(f);       atanf(f);      atanl(f);
 
@@ -174,9 +174,9 @@
 // HAS_ERRNO: declare double @atan(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @atanf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @atan(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @atanf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @atanl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @atan(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @atanf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @atanl(x86_fp80 noundef) [[NOT_READNONE]]
 
   atanh(f);      atanhf(f);     atanhl(f);
 
@@ -186,9 +186,9 @@
 // HAS_ERRNO: declare double @atanh(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @atanhf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @atanhl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @atanh(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @atanhf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @atanhl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @atanh(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @atanhf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @atanhl(x86_fp80 noundef) [[NOT_READNONE]]
 
   cbrt(f);       cbrtf(f);      cbrtl(f);
 
@@ -198,7 +198,7 @@
 // HAS_ERRNO: declare double @cbrt(double noundef) [[READNONE:#[0-9]+]]
 // HAS_ERRNO: declare float @cbrtf(float noundef) [[READNONE]]
 // HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare double @cbrt(double noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @cbrt(double noundef) [[READNONE:#[0-9]+]]
 // HAS_MAYTRAP: declare float @cbrtf(float noundef) [[READNONE]]
 // HAS_MAYTRAP: declare x86_fp80 @cbrtl(x86_fp80 noundef) [[READNONE]]
 
@@ -234,9 +234,9 @@
 // HAS_ERRNO: declare double @cosh(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @coshf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @cosh(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @coshf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @coshl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @cosh(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @coshf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @coshl(x86_fp80 noundef) [[NOT_READNONE]]
 
   erf(f);        erff(f);       erfl(f);
 
@@ -246,9 +246,9 @@
 // HAS_ERRNO: declare double @erf(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @erff(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @erfl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @erf(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @erff(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @erfl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @erf(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @erff(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @erfl(x86_fp80 noundef) [[NOT_READNONE]]
 
   erfc(f);       erfcf(f);      erfcl(f);
 
@@ -258,9 +258,9 @@
 // HAS_ERRNO: declare double @erfc(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @erfcf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @erfcl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @erfc(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @erfcf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @erfcl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @erfc(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @erfcf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @erfcl(x86_fp80 noundef) [[NOT_READNONE]]
 
   exp(f);        expf(f);       expl(f);
 
@@ -294,9 +294,9 @@
 // HAS_ERRNO: declare double @expm1(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @expm1f(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @expm1l(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @expm1(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @expm1f(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @expm1l(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @expm1(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @expm1f(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @expm1l(x86_fp80 noundef) [[NOT_READNONE]]
 
   fdim(f,f);       fdimf(f,f);      fdiml(f,f);
 
@@ -306,9 +306,9 @@
 // HAS_ERRNO: declare double @fdim(double noundef, double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @fdimf(float noundef, float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @fdiml(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @fdim(double noundef, double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @fdimf(float noundef, float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @fdiml(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @fdim(double noundef, double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @fdimf(float noundef, float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @fdiml(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
 
   floor(f);      floorf(f);     floorl(f);
 
@@ -378,9 +378,9 @@
 // HAS_ERRNO: declare double @hypot(double noundef, double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @hypotf(float noundef, float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @hypotl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @hypot(double noundef, double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @hypotf(float noundef, float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @hypotl(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @hypot(double noundef, double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @hypotf(float noundef, float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @hypotl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
 
   ilogb(f);      ilogbf(f);     ilogbl(f);
 
@@ -390,9 +390,9 @@
 // HAS_ERRNO: declare i32 @ilogb(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare i32 @ilogbf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare i32 @ilogbl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare i32 @ilogb(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare i32 @ilogbf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare i32 @ilogbl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare i32 @ilogb(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare i32 @ilogbf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare i32 @ilogbl(x86_fp80 noundef) [[NOT_READNONE]]
 
   lgamma(f);     lgammaf(f);    lgammal(f);
 
@@ -462,9 +462,9 @@
 // HAS_ERRNO: declare double @log1p(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @log1pf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @log1pl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @log1p(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @log1pf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @log1pl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @log1p(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @log1pf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @log1pl(x86_fp80 noundef) [[NOT_READNONE]]
 
   log2(f);       log2f(f);      log2l(f);
 
@@ -486,9 +486,9 @@
 // HAS_ERRNO: declare double @logb(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @logbf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @logbl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @logb(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @logbf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @logbl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @logb(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @logbf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @logbl(x86_fp80 noundef) [[NOT_READNONE]]
 
   lrint(f);      lrintf(f);     lrintl(f);
 
@@ -534,9 +534,9 @@
 // HAS_ERRNO: declare double @nextafter(double noundef, double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @nextafterf(float noundef, float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @nextafterl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @nextafter(double noundef, double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @nextafterf(float noundef, float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @nextafterl(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @nextafter(double noundef, double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @nextafterf(float noundef, float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @nextafterl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
 
   nexttoward(f,f); nexttowardf(f,f);nexttowardl(f,f);
 
@@ -546,9 +546,9 @@
 // HAS_ERRNO: declare double @nexttoward(double noundef, x86_fp80 noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @nexttowardf(float noundef, x86_fp80 noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @nexttowardl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @nexttoward(double noundef, x86_fp80 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @nexttowardf(float noundef, x86_fp80 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @nexttowardl(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @nexttoward(double noundef, x86_fp80 noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @nexttowardf(float noundef, x86_fp80 noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @nexttowardl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
 
   remainder(f,f);  remainderf(f,f); remainderl(f,f);
 
@@ -558,9 +558,9 @@
 // HAS_ERRNO: declare double @remainder(double noundef, double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @remainderf(float noundef, float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @remainderl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @remainder(double noundef, double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @remainderf(float noundef, float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @remainderl(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @remainder(double noundef, double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @remainderf(float noundef, float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @remainderl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
 
   remquo(f,f,i);  remquof(f,f,i); remquol(f,f,i);
 
@@ -606,9 +606,9 @@
 // HAS_ERRNO: declare double @scalbln(double noundef, i64 noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @scalblnf(float noundef, i64 noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @scalblnl(x86_fp80 noundef, i64 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @scalbln(double noundef, i64 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @scalblnf(float noundef, i64 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @scalblnl(x86_fp80 noundef, i64 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @scalbln(double noundef, i64 noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @scalblnf(float noundef, i64 noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @scalblnl(x86_fp80 noundef, i64 noundef) [[NOT_READNONE]]
 
   scalbn(f,f);     scalbnf(f,f);    scalbnl(f,f);
 
@@ -618,9 +618,9 @@
 // HAS_ERRNO: declare double @scalbn(double noundef, i32 noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @scalbnf(float noundef, i32 noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @scalbnl(x86_fp80 noundef, i32 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @scalbn(double noundef, i32 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @scalbnf(float noundef, i32 noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @scalbnl(x86_fp80 noundef, i32 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @scalbn(double noundef, i32 noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @scalbnf(float noundef, i32 noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @scalbnl(x86_fp80 noundef, i32 noundef) [[NOT_READNONE]]
 
   sin(f);        sinf(f);       sinl(f);
 
@@ -642,9 +642,9 @@
 // HAS_ERRNO: declare double @sinh(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @sinhf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @sinh(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @sinhf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @sinhl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @sinh(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @sinhf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @sinhl(x86_fp80 noundef) [[NOT_READNONE]]
 
   sqrt(f);       sqrtf(f);      sqrtl(f);
 
@@ -666,9 +666,9 @@
 // HAS_ERRNO: declare double @tan(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @tanf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @tan(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @tanf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @tanl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @tan(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @tanf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @tanl(x86_fp80 noundef) [[NOT_READNONE]]
 
   tanh(f);       tanhf(f);      tanhl(f);
 
@@ -678,9 +678,9 @@
 // HAS_ERRNO: declare double @tanh(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @tanhf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @tanh(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @tanhf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @tanhl(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @tanh(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @tanhf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @tanhl(x86_fp80 noundef) [[NOT_READNONE]]
 
   tgamma(f);     tgammaf(f);    tgammal(f);
 
@@ -690,9 +690,9 @@
 // HAS_ERRNO: declare double @tgamma(double noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare float @tgammaf(float noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @tgammal(x86_fp80 noundef) [[NOT_READNONE]]
-// HAS_MAYTRAP: declare double @tgamma(double noundef) [[READNONE]]
-// HAS_MAYTRAP: declare float @tgammaf(float noundef) [[READNONE]]
-// HAS_MAYTRAP: declare x86_fp80 @tgammal(x86_fp80 noundef) [[READNONE]]
+// HAS_MAYTRAP: declare double @tgamma(double noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare float @tgammaf(float noundef) [[NOT_READNONE]]
+// HAS_MAYTRAP: declare x86_fp80 @tgammal(x86_fp80 noundef) [[NOT_READNONE]]
 
   trunc(f);      truncf(f);     truncl(f);
 
@@ -714,8 +714,8 @@
 // HAS_ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} }
 // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 
-// HAS_MAYTRAP: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 // HAS_MAYTRAP: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
+// HAS_MAYTRAP: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 
 // HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
 // HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15676,11 +15676,20 @@
       FD->addAttr(CallbackAttr::CreateImplicit(
           Context, Encoding.data(), Encoding.size(), FD->getLocation()));
 
-    // 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.
-    if (!getLangOpts().MathErrno && !FD->hasAttr<ConstAttr>() &&
-        Context.BuiltinInfo.isConstWithoutErrno(BuiltinID))
+    // Mark const if we don't care about errno and/or floating point exceptions
+    // that are 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;
+    bool ConstWithoutErrnoAndExceptions =
+        Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
+    bool ConstWithoutExceptions =
+        Context.BuiltinInfo.isConstWithoutExceptions(BuiltinID);
+    if (!FD->hasAttr<ConstAttr>() &&
+        (ConstWithoutErrnoAndExceptions || ConstWithoutExceptions) &&
+        (!ConstWithoutErrnoAndExceptions ||
+         (!getLangOpts().MathErrno && NoExceptions)) &&
+        (!ConstWithoutExceptions || NoExceptions))
       FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
 
     // We make "fma" on GNU or Windows const because we know it does not set
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -2204,7 +2204,15 @@
   // might. Also, math builtins have the same semantics as their math library
   // twins. Thus, we can transform math library and builtin calls to their
   // LLVM counterparts if the call is marked 'const' (known to never set errno).
-  if (FD->hasAttr<ConstAttr>()) {
+  // In case FP exceptions are enabled, the experimental versions of the
+  // intrinsics model those.
+  bool ConstWithoutErrnoAndExceptions =
+      getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
+  bool ConstWithoutExceptions =
+      getContext().BuiltinInfo.isConstWithoutExceptions(BuiltinID);
+  if (FD->hasAttr<ConstAttr>() ||
+      ((ConstWithoutErrnoAndExceptions || ConstWithoutExceptions) &&
+       (!ConstWithoutErrnoAndExceptions || (!getLangOpts().MathErrno)))) {
     switch (BuiltinIDIfNoAsmLabel) {
     case Builtin::BIceil:
     case Builtin::BIceilf:
Index: clang/include/clang/Basic/Builtins.h
===================================================================
--- clang/include/clang/Basic/Builtins.h
+++ clang/include/clang/Basic/Builtins.h
@@ -228,13 +228,18 @@
                         llvm::SmallVectorImpl<int> &Encoding) const;
 
   /// Return true if this function has no side effects and doesn't
-  /// read memory, except for possibly errno.
+  /// read memory, except for possibly errno or raising FP exceptions.
   ///
-  /// Such functions can be const when the MathErrno lang option is disabled.
-  bool isConstWithoutErrno(unsigned ID) const {
+  /// Such functions can be const when the MathErrno lang option and FP
+  /// exceptions are disabled.
+  bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
     return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
+  bool isConstWithoutExceptions(unsigned ID) const {
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
+  }
+
   const char *getRequiredFeatures(unsigned ID) const {
     return getRecord(ID).Features;
   }
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -97,7 +97,8 @@
 //  S:N: -> similar to the s:N: attribute, but the function is like vscanf
 //          in that it accepts its arguments as a va_list rather than
 //          through an ellipsis
-//  e -> const, but only when -fno-math-errno
+//  e -> const, but only when -fno-math-errno and FP exceptions are ignored
+//  g -> 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
@@ -1340,7 +1341,7 @@
 LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
 
 // POSIX math.h declares a global, signgam, that lgamma writes to, so these
-// shouldn't have "e" or "c" attributes
+// shouldn't have "e", "c" or "g" attributes
 LIBBUILTIN(lgamma, "dd", "fn", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(lgammaf, "ff", "fn", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(lgammal, "LdLd", "fn", "math.h", ALL_LANGUAGES)
@@ -1401,13 +1402,13 @@
 LIBBUILTIN(remquof, "fffi*", "fn", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(remquol, "LdLdLdi*", "fn", "math.h", ALL_LANGUAGES)
 
-LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rint, "dd", "fng", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rintf, "ff", "fng", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rintl, "LdLd", "fng", "math.h", ALL_LANGUAGES)
 
-LIBBUILTIN(round, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(round, "dd", "fng", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundf, "ff", "fng", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundl, "LdLd", "fng", "math.h", ALL_LANGUAGES)
 
 LIBBUILTIN(scalbln, "ddLi", "fne", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(scalblnf, "ffLi", "fne", "math.h", ALL_LANGUAGES)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to