forked from OSchip/llvm-project
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:
parent
3f7796fc22
commit
18fa17cf3d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue