forked from OSchip/llvm-project
[Support] Add mathematical constants
Add own version of the mathematical constants from the upcoming C++20 `std::numbers`. Differential revision: https://reviews.llvm.org/D68257 llvm-svn: 374207
This commit is contained in:
parent
2e6f6b4dad
commit
e60415a0db
|
@ -39,6 +39,7 @@ unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
/// The behavior an operation has on an input of 0.
|
/// The behavior an operation has on an input of 0.
|
||||||
enum ZeroBehavior {
|
enum ZeroBehavior {
|
||||||
/// The returned value is undefined.
|
/// The returned value is undefined.
|
||||||
|
@ -49,6 +50,42 @@ enum ZeroBehavior {
|
||||||
ZB_Width
|
ZB_Width
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Mathematical constants.
|
||||||
|
namespace numbers {
|
||||||
|
// TODO: Track C++20 std::numbers.
|
||||||
|
// TODO: Favor using the hexadecimal FP constants (requires C++17).
|
||||||
|
constexpr double e = 2.7182818284590452354, // (0x1.5bf0a8b145749P+1) https://oeis.org/A001113
|
||||||
|
egamma = .57721566490153286061, // (0x1.2788cfc6fb619P-1) https://oeis.org/A001620
|
||||||
|
ln2 = .69314718055994530942, // (0x1.62e42fefa39efP-1) https://oeis.org/A002162
|
||||||
|
ln10 = 2.3025850929940456840, // (0x1.24bb1bbb55516P+1) https://oeis.org/A002392
|
||||||
|
log2e = 1.4426950408889634074, // (0x1.71547652b82feP+0)
|
||||||
|
log10e = .43429448190325182765, // (0x1.bcb7b1526e50eP-2)
|
||||||
|
pi = 3.1415926535897932385, // (0x1.921fb54442d18P+1) https://oeis.org/A000796
|
||||||
|
inv_pi = .31830988618379067154, // (0x1.45f306bc9c883P-2) https://oeis.org/A049541
|
||||||
|
sqrtpi = 1.7724538509055160273, // (0x1.c5bf891b4ef6bP+0) https://oeis.org/A002161
|
||||||
|
inv_sqrtpi = .56418958354775628695, // (0x1.20dd750429b6dP-1) https://oeis.org/A087197
|
||||||
|
sqrt2 = 1.4142135623730950488, // (0x1.6a09e667f3bcdP+0) https://oeis.org/A00219
|
||||||
|
inv_sqrt2 = .70710678118654752440, // (0x1.6a09e667f3bcdP-1)
|
||||||
|
sqrt3 = 1.7320508075688772935, // (0x1.bb67ae8584caaP+0) https://oeis.org/A002194
|
||||||
|
inv_sqrt3 = .57735026918962576451, // (0x1.279a74590331cP-1)
|
||||||
|
phi = 1.6180339887498948482; // (0x1.9e3779b97f4a8P+0) https://oeis.org/A001622
|
||||||
|
constexpr float ef = 2.71828183F, // (0x1.5bf0a8P+1) https://oeis.org/A001113
|
||||||
|
egammaf = .577215665F, // (0x1.2788d0P-1) https://oeis.org/A001620
|
||||||
|
ln2f = .693147181F, // (0x1.62e430P-1) https://oeis.org/A002162
|
||||||
|
ln10f = 2.30258509F, // (0x1.26bb1cP+1) https://oeis.org/A002392
|
||||||
|
log2ef = 1.44269504F, // (0x1.715476P+0)
|
||||||
|
log10ef = .434294482F, // (0x1.bcb7b2P-2)
|
||||||
|
pif = 3.14159265F, // (0x1.921fb6P+1) https://oeis.org/A000796
|
||||||
|
inv_pif = .318309886F, // (0x1.45f306P-2) https://oeis.org/A049541
|
||||||
|
sqrtpif = 1.77245385F, // (0x1.c5bf8aP+0) https://oeis.org/A002161
|
||||||
|
inv_sqrtpif = .564189584F, // (0x1.20dd76P-1) https://oeis.org/A087197
|
||||||
|
sqrt2f = 1.41421356F, // (0x1.6a09e6P+0) https://oeis.org/A002193
|
||||||
|
inv_sqrt2f = .707106781F, // (0x1.6a09e6P-1)
|
||||||
|
sqrt3f = 1.73205081F, // (0x1.bb67aeP+0) https://oeis.org/A002194
|
||||||
|
inv_sqrt3f = .577350269F, // (0x1.279a74P-1)
|
||||||
|
phif = 1.61803399F; // (0x1.9e377aP+0) https://oeis.org/A001622
|
||||||
|
} // namespace numbers
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
|
template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
|
||||||
static unsigned count(T Val, ZeroBehavior) {
|
static unsigned count(T Val, ZeroBehavior) {
|
||||||
|
|
|
@ -4974,12 +4974,11 @@ static SDValue expandExp(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
|
||||||
// Put the exponent in the right bit position for later addition to the
|
// Put the exponent in the right bit position for later addition to the
|
||||||
// final result:
|
// final result:
|
||||||
//
|
//
|
||||||
// #define LOG2OFe 1.4426950f
|
// t0 = Op * log2(e)
|
||||||
// t0 = Op * LOG2OFe
|
|
||||||
|
|
||||||
// TODO: What fast-math-flags should be set here?
|
// TODO: What fast-math-flags should be set here?
|
||||||
SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op,
|
SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op,
|
||||||
getF32Constant(DAG, 0x3fb8aa3b, dl));
|
DAG.getConstantFP(numbers::log2ef, dl, MVT::f32));
|
||||||
return getLimitedPrecisionExp2(t0, dl, DAG);
|
return getLimitedPrecisionExp2(t0, dl, DAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4997,10 +4996,11 @@ static SDValue expandLog(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
|
||||||
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
|
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
|
||||||
SDValue Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
|
SDValue Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
|
||||||
|
|
||||||
// Scale the exponent by log(2) [0.69314718f].
|
// Scale the exponent by log(2).
|
||||||
SDValue Exp = GetExponent(DAG, Op1, TLI, dl);
|
SDValue Exp = GetExponent(DAG, Op1, TLI, dl);
|
||||||
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
|
SDValue LogOfExponent =
|
||||||
getF32Constant(DAG, 0x3f317218, dl));
|
DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
|
||||||
|
DAG.getConstantFP(numbers::ln2f, dl, MVT::f32));
|
||||||
|
|
||||||
// Get the significand and build it into a floating-point number with
|
// Get the significand and build it into a floating-point number with
|
||||||
// exponent of 1.
|
// exponent of 1.
|
||||||
|
|
|
@ -48,7 +48,6 @@ static cl::opt<bool>
|
||||||
cl::desc("Enable unsafe double to float "
|
cl::desc("Enable unsafe double to float "
|
||||||
"shrinking for math lib calls"));
|
"shrinking for math lib calls"));
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Helper Functions
|
// Helper Functions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1941,9 +1940,8 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilder<> &B) {
|
||||||
ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
|
ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
|
||||||
Constant *Eul;
|
Constant *Eul;
|
||||||
if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
|
if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
|
||||||
// FIXME: The Euler number should be M_E, but it's place of definition
|
// FIXME: Add more precise value of e for long double.
|
||||||
// is not quite standard.
|
Eul = ConstantFP::get(Log->getType(), numbers::e);
|
||||||
Eul = ConstantFP::get(Log->getType(), 2.7182818284590452354);
|
|
||||||
else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
|
else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
|
||||||
Eul = ConstantFP::get(Log->getType(), 2.0);
|
Eul = ConstantFP::get(Log->getType(), 2.0);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue