@@ -37,6 +37,21 @@ import std.traits : isFloatingPoint, isIntegral, isSigned, isUnsigned, Largest,
3737static import core.math ;
3838static import core.stdc.math ;
3939
40+ version (LDC )
41+ {
42+ import ldc.intrinsics;
43+
44+ version (CRuntime_Microsoft ) version = LDC_MSVCRT ;
45+
46+ version (LDC_MSVCRT) {}
47+ else version (Android ) {}
48+ else
49+ {
50+ version (X86 ) version = INLINE_YL2X ;
51+ version (X86_64 ) version = INLINE_YL2X ;
52+ }
53+ }
54+
4055version (DigitalMars )
4156{
4257 version = INLINE_YL2X ; // x87 has opcodes for these
@@ -45,7 +60,9 @@ version (DigitalMars)
4560version (D_InlineAsm_X86 ) version = InlineAsm_X86_Any;
4661version (D_InlineAsm_X86_64 ) version = InlineAsm_X86_Any;
4762
48- version (InlineAsm_X86_Any) version = InlineAsm_X87;
63+ version (LDC_MSVCRT) {}
64+ else version (Android ) {}
65+ else version (InlineAsm_X86_Any) version = InlineAsm_X87;
4966version (InlineAsm_X87)
5067{
5168 static assert (real .mant_dig == 64 );
@@ -64,6 +81,17 @@ version (D_HardFloat)
6481Unqual! F pow (F, G)(F x, G n) @nogc @trusted pure nothrow
6582if (isFloatingPoint! (F) && isIntegral! (G))
6683{
84+ version (none )
85+ {
86+ // LDC: Leads to linking error on MSVC x64 as the intrinsic maps to
87+ // MSVC++ function `pow(double/float, int)` (a C++ template for
88+ // Visual Studio 2015).
89+ // Most likely not worth the effort anyway (and hindering CTFE).
90+ pragma (inline, true );
91+ return llvm_powi! (Unqual! F)(x, cast (int ) n);
92+ }
93+ else
94+ {
6795 import core.math : fabs;
6896 import std.math.rounding : floor;
6997 import std.math.traits : isNaN;
@@ -171,6 +199,7 @@ if (isFloatingPoint!(F) && isIntegral!(G))
171199 v *= v;
172200 }
173201 return p;
202+ } // !none
174203}
175204
176205// /
@@ -495,6 +524,13 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G))
495524
496525 alias Float = typeof (return );
497526
527+ version (none ) // LDC FIXME: Use of this LLVM intrinsic causes a unit test failure
528+ {
529+ pragma (inline, true );
530+ return llvm_pow! (Float)(x, y);
531+ }
532+ else
533+ {
498534 static real impl (real x, real y) @nogc pure nothrow
499535 {
500536 // Special cases.
@@ -700,6 +736,7 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G))
700736 }
701737 }
702738 return impl (x, y);
739+ } // !none
703740}
704741
705742// /
@@ -1033,6 +1070,18 @@ if (isUnsigned!F && isUnsigned!G && isUnsigned!H)
10331070 * $(TR $(TD $(NAN)) $(TD $(NAN)) )
10341071 * )
10351072 */
1073+ version (none ) // LDC FIXME: Use of this LLVM intrinsic causes a unit test failure
1074+ {
1075+ pragma (inline, true ):
1076+ real exp (real x) @safe pure nothrow @nogc { return llvm_exp(x); }
1077+ // /ditto
1078+ double exp (double x) @safe pure nothrow @nogc { return llvm_exp(x); }
1079+ // /ditto
1080+ float exp (float x) @safe pure nothrow @nogc { return llvm_exp(x); }
1081+ }
1082+ else
1083+ {
1084+
10361085pragma (inline, true )
10371086real exp (real x) @trusted pure nothrow @nogc // TODO: @safe
10381087{
@@ -1057,6 +1106,8 @@ double exp(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) exp
10571106pragma (inline, true )
10581107float exp (float x) @safe pure nothrow @nogc { return __ctfe ? cast (float ) exp(cast (real ) x) : expImpl(x); }
10591108
1109+ } // !none
1110+
10601111// /
10611112@safe unittest
10621113{
@@ -1740,6 +1791,18 @@ private T expm1Impl(T)(T x) @safe pure nothrow @nogc
17401791 * $(TR $(TD $(NAN)) $(TD $(NAN)) )
17411792 * )
17421793 */
1794+ version (none ) // LDC FIXME: Use of this LLVM intrinsic causes a unit test failure
1795+ {
1796+ pragma (inline, true ):
1797+ real exp2 (real x) @safe pure nothrow @nogc { return llvm_exp2(x); }
1798+ // /ditto
1799+ double exp2 (double x) @safe pure nothrow @nogc { return llvm_exp2(x); }
1800+ // /ditto
1801+ float exp2 (float x) @safe pure nothrow @nogc { return llvm_exp2(x); }
1802+ }
1803+ else
1804+ {
1805+
17431806pragma (inline, true )
17441807real exp2 (real x) @nogc @trusted pure nothrow // TODO: @safe
17451808{
@@ -1759,6 +1822,8 @@ double exp2(double x) @nogc @safe pure nothrow { return __ctfe ? cast(double) ex
17591822pragma (inline, true )
17601823float exp2 (float x) @nogc @safe pure nothrow { return __ctfe ? cast (float ) exp2(cast (real ) x) : exp2Impl(x); }
17611824
1825+ } // !none
1826+
17621827// /
17631828@safe unittest
17641829{
@@ -3038,6 +3103,16 @@ private
30383103 * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no))
30393104 * )
30403105 */
3106+ version (LDC )
3107+ {
3108+ pragma (inline, true ):
3109+ real log (real x) @safe pure nothrow @nogc { return llvm_log(x); }
3110+ // double log(double x) @safe pure nothrow @nogc { return llvm_log(x); }
3111+ // float log(float x) @safe pure nothrow @nogc { return llvm_log(x); }
3112+ }
3113+ else
3114+ {
3115+
30413116real log (real x) @safe pure nothrow @nogc
30423117{
30433118 import std.math.constants : LN2 , LOG2 , SQRT1_2 ;
@@ -3119,6 +3194,8 @@ real log(real x) @safe pure nothrow @nogc
31193194 }
31203195}
31213196
3197+ } // !LDC
3198+
31223199// /
31233200@safe pure nothrow @nogc unittest
31243201{
@@ -3138,6 +3215,16 @@ real log(real x) @safe pure nothrow @nogc
31383215 * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no))
31393216 * )
31403217 */
3218+ version (LDC )
3219+ {
3220+ pragma (inline, true ):
3221+ real log10 (real x) @safe pure nothrow @nogc { return llvm_log10(x); }
3222+ // double log10(double x) @safe pure nothrow @nogc { return llvm_log10(x); }
3223+ // float log10(float x) @safe pure nothrow @nogc { return llvm_log10(x); }
3224+ }
3225+ else
3226+ {
3227+
31413228real log10 (real x) @safe pure nothrow @nogc
31423229{
31433230 import std.math.constants : LOG2 , LN2 , SQRT1_2 ;
@@ -3223,6 +3310,8 @@ real log10(real x) @safe pure nothrow @nogc
32233310 }
32243311}
32253312
3313+ } // !LDC
3314+
32263315// /
32273316@safe pure nothrow @nogc unittest
32283317{
@@ -3299,6 +3388,16 @@ real log1p(real x) @safe pure nothrow @nogc
32993388 * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no) )
33003389 * )
33013390 */
3391+ version (LDC )
3392+ {
3393+ pragma (inline, true ):
3394+ real log2 (real x) @safe pure nothrow @nogc { return llvm_log2(x); }
3395+ // double log2(double x) @safe pure nothrow @nogc { return llvm_log2(x); }
3396+ // float log2(float x) @safe pure nothrow @nogc { return llvm_log2(x); }
3397+ }
3398+ else
3399+ {
3400+
33023401real log2 (real x) @safe pure nothrow @nogc
33033402{
33043403 import std.math.traits : isNaN, isInfinity, signbit;
@@ -3375,6 +3474,8 @@ real log2(real x) @safe pure nothrow @nogc
33753474 }
33763475}
33773476
3477+ } // !LDC
3478+
33783479// /
33793480@safe unittest
33803481{
0 commit comments