Index: llvm/include/llvm/Support/MathExtras.h =================================================================== --- llvm/include/llvm/Support/MathExtras.h +++ llvm/include/llvm/Support/MathExtras.h @@ -39,6 +39,7 @@ #endif namespace llvm { + /// The behavior an operation has on an input of 0. enum ZeroBehavior { /// The returned value is undefined. @@ -49,6 +50,26 @@ ZB_Width }; +/// Mathematical constants. +namespace numbers { +// FIXME: Use values from std:numbers in C++20 when possible. +constexpr double e = 2.7182818284590452353602874713526624977572470937000, // https://oeis.org/A001113 + egamma = 0.57721566490153286060651209008240243104215933593992, // https://oeis.org/A001620 + ln2 = 0.69314718055994530941723212145817656807550013436026, // https://oeis.org/A002162 + ln10 = 2.3025850929940456840179914546843642076011014886288, // https://oeis.org/A002392 + log2e = 1.4426950408889634073599246810018921374266459541530, + log10e = 0.43429448190325182765112891891660508229439700580366, + pi = 3.1415926535897932384626433832795028841971693993751, // https://oeis.org/A000796 + inv_pi = 0.31830988618379067153776752674502872406891929148091, // https://oeis.org/A049541 + sqrtpi = 1.7724538509055160272981674833411451827975494561224, // https://oeis.org/A002161 + inv_sqrtpi = 0.56418958354775628694807945156077258584405062932900, // https://oeis.org/A087197 + sqrt2 = 1.4142135623730950488016887242096980785696718753770, // https://oeis.org/A002193 + inv_sqrt2 = 0.70710678118654752440084436210484903928483593768844, + sqrt3 = 1.7320508075688772935274463415058723669428052538104, // https://oeis.org/A002194 + inv_sqrt3 = 0.57735026918962576450914878050195745564760175127012, + phi = 1.6180339887498948482045868343656381177203091798058; // https://oeis.org/A001622 +} // namespace numbers + namespace detail { template struct TrailingZerosCounter { static unsigned count(T Val, ZeroBehavior) { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4969,12 +4969,11 @@ // Put the exponent in the right bit position for later addition to the // final result: // - // #define LOG2OFe 1.4426950f - // t0 = Op * LOG2OFe + // t0 = Op * log2(e) // TODO: What fast-math-flags should be set here? SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op, - getF32Constant(DAG, 0x3fb8aa3b, dl)); + DAG.getConstantFP(numbers::log2e, dl, MVT::f32)); return getLimitedPrecisionExp2(t0, dl, DAG); } @@ -4992,10 +4991,11 @@ LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { 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 LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp, - getF32Constant(DAG, 0x3f317218, dl)); + SDValue LogOfExponent = + DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp, + DAG.getConstantFP(numbers::ln2, dl, MVT::f32)); // Get the significand and build it into a floating-point number with // exponent of 1. Index: llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -12,10 +12,6 @@ // //===----------------------------------------------------------------------===// -#define AMDGPU_LOG2E_F 1.44269504088896340735992468100189214f -#define AMDGPU_LN2_F 0.693147180559945309417232121458176568f -#define AMDGPU_LN10_F 2.30258509299404568401799145468436421f - #include "AMDGPUISelLowering.h" #include "AMDGPU.h" #include "AMDGPUCallLowering.h" @@ -37,6 +33,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/Support/KnownBits.h" +#include "llvm/Support/MathExtras.h" using namespace llvm; #include "AMDGPUGenCallingConv.inc" @@ -1135,9 +1132,9 @@ case ISD::FROUND: return LowerFROUND(Op, DAG); case ISD::FFLOOR: return LowerFFLOOR(Op, DAG); case ISD::FLOG: - return LowerFLOG(Op, DAG, 1 / AMDGPU_LOG2E_F); + return LowerFLOG(Op, DAG, 1.0 / numbers::log2e); case ISD::FLOG10: - return LowerFLOG(Op, DAG, AMDGPU_LN2_F / AMDGPU_LN10_F); + return LowerFLOG(Op, DAG, numbers::ln2 / numbers::ln10); case ISD::FEXP: return lowerFEXP(Op, DAG); case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); @@ -2285,30 +2282,13 @@ return DAG.getNode(ISD::FMUL, SL, VT, Log2Operand, Log2BaseInvertedOperand); } -// Return M_LOG2E of appropriate type -static SDValue getLog2EVal(SelectionDAG &DAG, const SDLoc &SL, EVT VT) { - switch (VT.getScalarType().getSimpleVT().SimpleTy) { - case MVT::f32: - return DAG.getConstantFP(1.44269504088896340735992468100189214f, SL, VT); - case MVT::f16: - return DAG.getConstantFP( - APFloat(APFloat::IEEEhalf(), "1.44269504088896340735992468100189214"), - SL, VT); - case MVT::f64: - return DAG.getConstantFP( - APFloat(APFloat::IEEEdouble(), "0x1.71547652b82fep+0"), SL, VT); - default: - llvm_unreachable("unsupported fp type"); - } -} - // exp2(M_LOG2E_F * f); SDValue AMDGPUTargetLowering::lowerFEXP(SDValue Op, SelectionDAG &DAG) const { EVT VT = Op.getValueType(); SDLoc SL(Op); SDValue Src = Op.getOperand(0); - const SDValue K = getLog2EVal(DAG, SL, VT); + const SDValue K = DAG.getConstantFP(numbers::log2e, SL, VT); SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, Src, K, Op->getFlags()); return DAG.getNode(ISD::FEXP2, SL, VT, Mul, Op->getFlags()); } Index: llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp +++ llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -48,18 +49,10 @@ cl::CommaSeparated, cl::ValueOptional, cl::Hidden); -#define MATH_PI 3.14159265358979323846264338327950288419716939937511 -#define MATH_E 2.71828182845904523536028747135266249775724709369996 -#define MATH_SQRT2 1.41421356237309504880168872420969807856967187537695 - -#define MATH_LOG2E 1.4426950408889634073599246810018921374266459541529859 -#define MATH_LOG10E 0.4342944819032518276511289189166050822943970058036665 -// Value of log2(10) -#define MATH_LOG2_10 3.3219280948873623478703194294893901758648313930245806 -// Value of 1 / log2(10) -#define MATH_RLOG2_10 0.3010299956639811952137388947244930267681898814621085 -// Value of 1 / M_LOG2E_F = 1 / log2(e) -#define MATH_RLOG2_E 0.6931471805599453094172321214581765680755001343602552 +#define MATH_PI numbers::pi +#define MATH_E numbers::e +#define MATH_SQRT2 numbers::sqrt2 +#define MATH_SQRT1_2 numbers::inv_sqrt2 namespace llvm { @@ -359,7 +352,7 @@ }; static const TableEntry tbl_rsqrt[] = { {1.0, 1.0}, - {1.0/MATH_SQRT2, 2.0} + {MATH_SQRT1_2, 2.0} }; static const TableEntry tbl_sin[] = { {0.0, 0.0}, @@ -868,7 +861,7 @@ #if _XOPEN_SOURCE >= 600 || defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L return ::log2(V); #else - return log(V) / 0.693147180559945309417; + return log(V) / numbers::ln2; #endif } } Index: llvm/lib/Target/AMDGPU/R600ISelLowering.cpp =================================================================== --- llvm/lib/Target/AMDGPU/R600ISelLowering.cpp +++ llvm/lib/Target/AMDGPU/R600ISelLowering.cpp @@ -41,6 +41,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MachineValueType.h" +#include "llvm/Support/MathExtras.h" #include #include #include @@ -782,7 +783,7 @@ return TrigVal; // On R600 hw, COS/SIN input must be between -Pi and Pi. return DAG.getNode(ISD::FMUL, DL, VT, TrigVal, - DAG.getConstantFP(3.14159265359, DL, MVT::f32)); + DAG.getConstantFP(numbers::pi, DL, MVT::f32)); } SDValue R600TargetLowering::LowerSHLParts(SDValue Op, SelectionDAG &DAG) const { Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -48,7 +48,6 @@ cl::desc("Enable unsafe double to float " "shrinking for math lib calls")); - //===----------------------------------------------------------------------===// // Helper Functions //===----------------------------------------------------------------------===// @@ -1941,9 +1940,7 @@ ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) { Constant *Eul; if (ArgLb == ExpLb || ArgID == Intrinsic::exp) - // FIXME: The Euler number should be M_E, but it's place of definition - // is not quite standard. - Eul = ConstantFP::get(Log->getType(), 2.7182818284590452354); + Eul = ConstantFP::get(Log->getType(), numbers::e); else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2) Eul = ConstantFP::get(Log->getType(), 2.0); else Index: llvm/test/CodeGen/AMDGPU/llvm.log10.f16.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/llvm.log10.f16.ll +++ llvm/test/CodeGen/AMDGPU/llvm.log10.f16.ll @@ -11,7 +11,7 @@ ; GFX9: global_load_ushort v[[A_F16_0:[0-9]+]] ; SI: v_cvt_f32_f16_e32 v[[A_F32_0:[0-9]+]], v[[A_F16_0]] ; SI: v_log_f32_e32 v[[R_F32_0:[0-9]+]], v[[A_F32_0]] -; SI: v_mul_f32_e32 v[[R_F32_1:[0-9]+]], 0x3e9a209a, v[[R_F32_0]] +; SI: v_mul_f32_e32 v[[R_F32_1:[0-9]+]], 0x3e9a209b, v[[R_F32_0]] ; SI: v_cvt_f16_f32_e32 v[[R_F16_0:[0-9]+]], v[[R_F32_1]] ; VIGFX9: v_log_f16_e32 v[[R_F16_0:[0-9]+]], v[[A_F16_0]] ; VIGFX9: v_mul_f16_e32 v[[R_F16_0]], 0x34d1, v[[R_F16_0]] @@ -32,7 +32,7 @@ ; SI: buffer_load_dword v[[A_F16_0:[0-9]+]] ; VI: flat_load_dword v[[A_F16_0:[0-9]+]] ; GFX9: global_load_dword v[[A_F16_0:[0-9]+]] -; SI: s_mov_b32 [[A_F32_2:s[0-9]+]], 0x3e9a209a +; SI: s_mov_b32 [[A_F32_2:s[0-9]+]], 0x3e9a209b ; VIGFX9: s_movk_i32 [[A_F32_2:s[0-9]+]], 0x34d1 ; VI: v_mov_b32_e32 [[A_F32_2_V:v[0-9]+]], [[A_F32_2]] ; SI: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_F16_0]] Index: llvm/test/CodeGen/AMDGPU/llvm.log10.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/llvm.log10.ll +++ llvm/test/CodeGen/AMDGPU/llvm.log10.ll @@ -10,7 +10,7 @@ ; CM-DAG: LOG_IEEE T{{[0-9]+\.[XYZW]}} (MASKED) ; CM-DAG: LOG_IEEE T{{[0-9]+\.[XYZW]}} ; GCN: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}} -; GCN: v_mul_f32_e32 v{{[0-9]+}}, 0x3e9a209a, v{{[0-9]+}} +; GCN: v_mul_f32_e32 v{{[0-9]+}}, 0x3e9a209b, v{{[0-9]+}} define void @test(float addrspace(1)* %out, float %in) { entry: %res = call float @llvm.log10.f32(float %in) @@ -32,7 +32,7 @@ ; CM-DAG: LOG_IEEE T{{[0-9]+\.[XYZW]}} ; CM-DAG: LOG_IEEE T{{[0-9]+\.[XYZW]}} ; GCN-DAG: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}} -; GCN-DAG: s_mov_b32 [[R_F32_LOG_CONST:s[0-9]+]], 0x3e9a209a +; GCN-DAG: s_mov_b32 [[R_F32_LOG_CONST:s[0-9]+]], 0x3e9a209b ; GCN-DAG: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}} ; GCN: v_mul_f32_e32 v{{[0-9]+}}, [[R_F32_LOG_CONST]], v{{[0-9]+}} ; GCN: v_mul_f32_e32 v{{[0-9]+}}, [[R_F32_LOG_CONST]], v{{[0-9]+}} @@ -67,7 +67,7 @@ ; CM-DAG: LOG_IEEE T{{[0-9]+\.[XYZW]}} ; CM-DAG: LOG_IEEE T{{[0-9]+\.[XYZW]}} ; GCN-DAG: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}} -; GCN-DAG: s_mov_b32 [[R_F32_LOG_CONST:s[0-9]+]], 0x3e9a209a +; GCN-DAG: s_mov_b32 [[R_F32_LOG_CONST:s[0-9]+]], 0x3e9a209b ; GCN-DAG: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}} ; GCN-DAG: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}} ; GCN-DAG: v_log_f32_e32 v{{[0-9]+}}, v{{[0-9]+}}