Fix the folding of floating-point math library calls, like sin(infinity),

so that it detects errors on platforms where libm doesn't set errno.
It's still subject to host libm details though.

llvm-svn: 114148
This commit is contained in:
Dan Gohman 2010-09-17 01:38:06 +00:00
parent 3f7796fc22
commit 18fa17cf3d
2 changed files with 28 additions and 2 deletions

View File

@ -32,6 +32,7 @@
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
#include <fenv.h>
using namespace llvm;
//===----------------------------------------------------------------------===//
@ -1039,9 +1040,12 @@ llvm::canConstantFoldCallTo(const Function *F) {
static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
const Type *Ty) {
feclearexcept(FE_ALL_EXCEPT);
errno = 0;
V = NativeFP(V);
if (errno != 0) {
if (errno != 0 ||
fetestexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)) {
feclearexcept(FE_ALL_EXCEPT);
errno = 0;
return 0;
}
@ -1056,9 +1060,12 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
double V, double W, const Type *Ty) {
feclearexcept(FE_ALL_EXCEPT);
errno = 0;
V = NativeFP(V, W);
if (errno != 0) {
if (errno != 0 ||
fetestexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)) {
feclearexcept(FE_ALL_EXCEPT);
errno = 0;
return 0;
}

View File

@ -0,0 +1,19 @@
; RUN: opt -instcombine -S < %s | FileCheck %s
; This shouldn't fold, because sin(inf) is invalid.
; CHECK: @foo
; CHECK: %t = call double @sin(double 0x7FF0000000000000)
define double @foo() {
%t = call double @sin(double 0x7FF0000000000000)
ret double %t
}
; This should fold.
; CHECK: @bar
; CHECK: ret double 0x3FDA6026360C2F91
define double @bar() {
%t = call double @sin(double 9.0)
ret double %t
}
declare double @sin(double)