forked from OSchip/llvm-project
[CodeGen] fix mapping from fmod calls to frem instruction
Similar to D40044 and discussed in D40594. llvm-svn: 319619
This commit is contained in:
parent
0c0f77d03d
commit
08fba37e9d
|
@ -854,12 +854,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
Result.Val.getFloat()));
|
||||
}
|
||||
|
||||
// Math builtins have the same semantics as their math library twins.
|
||||
// There are LLVM math intrinsics corresponding to math library functions
|
||||
// except the intrinsic will never set errno while the math library might.
|
||||
// Thus, we can transform math library and builtin calls to their
|
||||
// semantically-equivalent LLVM intrinsic counterparts if the call is marked
|
||||
// 'const' (it is known to never set errno).
|
||||
// There are LLVM math intrinsics/instructions corresponding to math library
|
||||
// functions except the LLVM op will never set errno while the math library
|
||||
// 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>()) {
|
||||
switch (BuiltinID) {
|
||||
case Builtin::BIceil:
|
||||
|
@ -942,6 +941,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
case Builtin::BI__builtin_fminl:
|
||||
return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum));
|
||||
|
||||
// fmod() is a special-case. It maps to the frem instruction rather than an
|
||||
// LLVM intrinsic.
|
||||
case Builtin::BIfmod:
|
||||
case Builtin::BIfmodf:
|
||||
case Builtin::BIfmodl:
|
||||
case Builtin::BI__builtin_fmod:
|
||||
case Builtin::BI__builtin_fmodf:
|
||||
case Builtin::BI__builtin_fmodl: {
|
||||
Value *Arg1 = EmitScalarExpr(E->getArg(0));
|
||||
Value *Arg2 = EmitScalarExpr(E->getArg(1));
|
||||
return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod"));
|
||||
}
|
||||
|
||||
case Builtin::BIlog:
|
||||
case Builtin::BIlogf:
|
||||
case Builtin::BIlogl:
|
||||
|
@ -1067,14 +1079,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
|
||||
return RValue::get(Result);
|
||||
}
|
||||
case Builtin::BI__builtin_fmod:
|
||||
case Builtin::BI__builtin_fmodf:
|
||||
case Builtin::BI__builtin_fmodl: {
|
||||
Value *Arg1 = EmitScalarExpr(E->getArg(0));
|
||||
Value *Arg2 = EmitScalarExpr(E->getArg(1));
|
||||
Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod");
|
||||
return RValue::get(Result);
|
||||
}
|
||||
case Builtin::BI__builtin_conj:
|
||||
case Builtin::BI__builtin_conjf:
|
||||
case Builtin::BI__builtin_conjl: {
|
||||
|
|
|
@ -6,12 +6,21 @@
|
|||
// Test attributes and codegen of math builtins.
|
||||
|
||||
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);
|
||||
|
||||
// NO__ERRNO: frem double
|
||||
// NO__ERRNO: frem float
|
||||
// NO__ERRNO: frem x86_fp80
|
||||
// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE:#[0-9]+]]
|
||||
// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
|
||||
|
||||
__builtin_atan2(f,f); __builtin_atan2f(f,f) ; __builtin_atan2l(f, f);
|
||||
|
||||
// NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]]
|
||||
// NO__ERRNO: declare float @atan2f(float, float) [[READNONE]]
|
||||
// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]]
|
||||
// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE:#[0-9]+]]
|
||||
// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]]
|
||||
|
||||
|
@ -33,13 +42,6 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
|
|||
// HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
|
||||
// HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
|
||||
|
||||
__builtin_fmod(f,f); __builtin_fmodf(f,f); __builtin_fmodl(f,f);
|
||||
|
||||
// NO__ERRNO-NOT: .fmod
|
||||
// NO__ERRNO-NOT: @fmod
|
||||
// HAS_ERRNO-NOT: .fmod
|
||||
// HAS_ERRNO-NOT: @fmod
|
||||
|
||||
__builtin_frexp(f,i); __builtin_frexpf(f,i); __builtin_frexpl(f,i);
|
||||
|
||||
// NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]]
|
||||
|
|
|
@ -6,12 +6,21 @@
|
|||
// Test attributes and builtin codegen of math library calls.
|
||||
|
||||
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, double) [[NOT_READNONE:#[0-9]+]]
|
||||
// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
|
||||
|
||||
atan2(f,f); atan2f(f,f) ; atan2l(f, f);
|
||||
|
||||
// NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]]
|
||||
// NO__ERRNO: declare float @atan2f(float, float) [[READNONE]]
|
||||
// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]]
|
||||
// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE:#[0-9]+]]
|
||||
// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]]
|
||||
|
||||
|
@ -33,15 +42,6 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
|
|||
// HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
|
||||
// HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
|
||||
|
||||
fmod(f,f); fmodf(f,f); fmodl(f,f);
|
||||
|
||||
// NO__ERRNO: declare double @fmod(double, double) [[READNONE]]
|
||||
// NO__ERRNO: declare float @fmodf(float, float) [[READNONE]]
|
||||
// NO__ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[READNONE]]
|
||||
// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
|
||||
// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
|
||||
|
||||
frexp(f,i); frexpf(f,i); frexpl(f,i);
|
||||
|
||||
// NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]]
|
||||
|
|
Loading…
Reference in New Issue