Math builtin definition tweaks.
There were missed optimizations when the system headers didn't have attributes
in place, specifically:
- Add copysign, exp2, log2, nearbyint, rint and trunc to the list.
These are functions that get inlined by LLVM's optimizer, but only when they
have the right attributes.
- Mark copysign, fabs, fmax, fmin and trunc const unconditionally.
Previously these were only const with -fno-math-errno, but they never set
errno per POSIX.
For ceil/floor/nearbyint/round I'm not aware of any implementation that sets
errno, but POSIX says it may signal overflow so I left them alone for now.
llvm-svn: 162375
2012-08-23 02:16:02 +08:00
|
|
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=CHECK-NOERRNO
|
2012-08-23 02:50:01 +08:00
|
|
|
// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=CHECK-ERRNO
|
Math builtin definition tweaks.
There were missed optimizations when the system headers didn't have attributes
in place, specifically:
- Add copysign, exp2, log2, nearbyint, rint and trunc to the list.
These are functions that get inlined by LLVM's optimizer, but only when they
have the right attributes.
- Mark copysign, fabs, fmax, fmin and trunc const unconditionally.
Previously these were only const with -fno-math-errno, but they never set
errno per POSIX.
For ceil/floor/nearbyint/round I'm not aware of any implementation that sets
errno, but POSIX says it may signal overflow so I left them alone for now.
llvm-svn: 162375
2012-08-23 02:16:02 +08:00
|
|
|
|
|
|
|
// Prototypes.
|
|
|
|
double acos(double);
|
|
|
|
long double acosl(long double);
|
|
|
|
float acosf(float);
|
|
|
|
double asin(double);
|
|
|
|
long double asinl(long double);
|
|
|
|
float asinf(float);
|
|
|
|
double atan(double);
|
|
|
|
long double atanl(long double);
|
|
|
|
float atanf(float);
|
|
|
|
double atan2(double, double);
|
|
|
|
long double atan2l(long double, long double);
|
|
|
|
float atan2f(float, float);
|
|
|
|
double ceil(double);
|
|
|
|
long double ceill(long double);
|
|
|
|
float ceilf(float);
|
|
|
|
double copysign(double, double);
|
|
|
|
long double copysignl(long double, long double);
|
|
|
|
float copysignf(float, float);
|
|
|
|
double cos(double);
|
|
|
|
long double cosl(long double);
|
|
|
|
float cosf(float);
|
|
|
|
double exp(double);
|
|
|
|
long double expl(long double);
|
|
|
|
float expf(float);
|
|
|
|
double exp2(double);
|
|
|
|
long double exp2l(long double);
|
|
|
|
float exp2f(float);
|
|
|
|
double fabs(double);
|
|
|
|
long double fabsl(long double);
|
|
|
|
float fabsf(float);
|
|
|
|
double floor(double);
|
|
|
|
long double floorl(long double);
|
|
|
|
float floorf(float);
|
|
|
|
double fma(double, double, double);
|
|
|
|
long double fmal(long double, long double, long double);
|
|
|
|
float fmaf(float, float, float);
|
|
|
|
double fmax(double, double);
|
|
|
|
long double fmaxl(long double, long double);
|
|
|
|
float fmaxf(float, float);
|
|
|
|
double fmin(double, double);
|
|
|
|
long double fminl(long double, long double);
|
|
|
|
float fminf(float, float);
|
|
|
|
double log(double);
|
|
|
|
long double logl(long double);
|
|
|
|
float logf(float);
|
|
|
|
double log2(double);
|
|
|
|
long double log2l(long double);
|
|
|
|
float log2f(float);
|
|
|
|
double nearbyint(double);
|
|
|
|
long double nearbyintl(long double);
|
|
|
|
float nearbyintf(float);
|
|
|
|
double pow(double, double);
|
|
|
|
long double powl(long double, long double);
|
|
|
|
float powf(float, float);
|
|
|
|
double rint(double);
|
|
|
|
long double rintl(long double);
|
|
|
|
float rintf(float);
|
|
|
|
double round(double);
|
|
|
|
long double roundl(long double);
|
|
|
|
float roundf(float);
|
|
|
|
double sin(double);
|
|
|
|
long double sinl(long double);
|
|
|
|
float sinf(float);
|
|
|
|
double sqrt(double);
|
|
|
|
long double sqrtl(long double);
|
|
|
|
float sqrtf(float);
|
|
|
|
double tan(double);
|
|
|
|
long double tanl(long double);
|
|
|
|
float tanf(float);
|
|
|
|
double trunc(double);
|
|
|
|
long double truncl(long double);
|
|
|
|
float truncf(float);
|
|
|
|
|
|
|
|
// Force emission of the declare statements.
|
|
|
|
void *use[] = {
|
|
|
|
acos, acosl, acosf, asin, asinl, asinf, atan, atanl, atanf, atan2, atan2l,
|
|
|
|
atan2f, ceil, ceill, ceilf, copysign, copysignl, copysignf, cos, cosl, cosf,
|
|
|
|
exp, expl, expf, exp2, exp2l, exp2f, fabs, fabsl, fabsf, floor, floorl,
|
|
|
|
floorf, fma, fmal, fmaf, fmax, fmaxl, fmaxf, fmin, fminl, fminf, log, logl,
|
|
|
|
logf, log2, log2l, log2f, nearbyint, nearbyintl, nearbyintf, pow, powl, powf,
|
|
|
|
rint, rintl, rintf, round, roundl, roundf, sin, sinl, sinf, sqrt, sqrtl,
|
|
|
|
sqrtf, tan, tanl, tanf, trunc, truncl, truncf
|
|
|
|
};
|
|
|
|
|
2013-02-26 03:51:03 +08:00
|
|
|
// CHECK-NOERRNO: declare double @acos(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @acosl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @acosf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @asin(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @asinl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @asinf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @atan(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @atanl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @atanf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @atan2(double, double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @atan2f(float, float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @ceil(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @ceill(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @ceilf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @copysign(double, double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @copysignf(float, float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @cos(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @cosl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @cosf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @exp(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @expl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @expf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @exp2(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @exp2l(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @exp2f(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @fabs(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @fabsl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @fabsf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @floor(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @floorl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @floorf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @fma(double, double, double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @fmaf(float, float, float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @fmax(double, double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @fmaxf(float, float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @fmin(double, double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @fminf(float, float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @log(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @logl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @logf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @log2(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @log2l(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @log2f(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @nearbyint(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @nearbyintl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @nearbyintf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @pow(double, double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @powf(float, float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @rint(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @rintl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @rintf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @round(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @roundl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @roundf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @sin(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @sinl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @sinf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @sqrt(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @sqrtl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @sqrtf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @tan(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @tanl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @tanf(float) #0
|
|
|
|
// CHECK-NOERRNO: declare double @trunc(double) #0
|
|
|
|
// CHECK-NOERRNO: declare x86_fp80 @truncl(x86_fp80) #0
|
|
|
|
// CHECK-NOERRNO: declare float @truncf(float) #0
|
Math builtin definition tweaks.
There were missed optimizations when the system headers didn't have attributes
in place, specifically:
- Add copysign, exp2, log2, nearbyint, rint and trunc to the list.
These are functions that get inlined by LLVM's optimizer, but only when they
have the right attributes.
- Mark copysign, fabs, fmax, fmin and trunc const unconditionally.
Previously these were only const with -fno-math-errno, but they never set
errno per POSIX.
For ceil/floor/nearbyint/round I'm not aware of any implementation that sets
errno, but POSIX says it may signal overflow so I left them alone for now.
llvm-svn: 162375
2012-08-23 02:16:02 +08:00
|
|
|
|
2013-02-26 03:51:03 +08:00
|
|
|
// CHECK-ERRNO: declare double @ceil(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @ceill(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @ceilf(float) #1
|
|
|
|
// CHECK-ERRNO: declare double @copysign(double, double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @copysignf(float, float) #1
|
|
|
|
// CHECK-ERRNO: declare double @fabs(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @fabsl(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @fabsf(float) #1
|
|
|
|
// CHECK-ERRNO: declare double @floor(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @floorl(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @floorf(float) #1
|
|
|
|
// CHECK-ERRNO: declare double @fmax(double, double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @fmaxf(float, float) #1
|
|
|
|
// CHECK-ERRNO: declare double @fmin(double, double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @fminf(float, float) #1
|
|
|
|
// CHECK-ERRNO: declare double @nearbyint(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @nearbyintf(float) #1
|
|
|
|
// CHECK-ERRNO: declare double @rint(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @rintl(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @rintf(float) #1
|
|
|
|
// CHECK-ERRNO: declare double @round(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @roundl(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @roundf(float) #1
|
|
|
|
// CHECK-ERRNO: declare double @trunc(double) #1
|
|
|
|
// CHECK-ERRNO: declare x86_fp80 @truncl(x86_fp80) #1
|
|
|
|
// CHECK-ERRNO: declare float @truncf(float) #1
|
2013-02-20 15:22:19 +08:00
|
|
|
|
2013-02-26 03:51:03 +08:00
|
|
|
// CHECK-NOERRNO: attributes #0 = { nounwind readnone "target-features"={{.*}} }
|
2013-02-20 15:22:19 +08:00
|
|
|
|
2013-02-26 03:51:03 +08:00
|
|
|
// CHECK-ERRNO: attributes #0 = { "target-features"={{.*}} }
|
|
|
|
// CHECK-ERRNO: attributes #1 = { nounwind readnone "target-features"={{.*}} }
|