Skip to content

Commit b3efcea

Browse files
committed
LDC: Re-apply std.math LDC specifics to new std.math package
1 parent ac4eb41 commit b3efcea

File tree

7 files changed

+588
-44
lines changed

7 files changed

+588
-44
lines changed

std/math/algebraic.d

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,26 @@ real fabs(real x) @safe pure nothrow @nogc { return core.math.fabs(x); }
132132
pragma(inline, true)
133133
double fabs(double d) @trusted pure nothrow @nogc
134134
{
135-
ulong tmp = *cast(ulong*)&d & 0x7FFF_FFFF_FFFF_FFFF;
136-
return *cast(double*)&tmp;
135+
version (LDC)
136+
return core.math.fabs(d);
137+
else
138+
{
139+
ulong tmp = *cast(ulong*)&d & 0x7FFF_FFFF_FFFF_FFFF;
140+
return *cast(double*)&tmp;
141+
}
137142
}
138143

139144
///ditto
140145
pragma(inline, true)
141146
float fabs(float f) @trusted pure nothrow @nogc
142147
{
143-
uint tmp = *cast(uint*)&f & 0x7FFF_FFFF;
144-
return *cast(float*)&tmp;
148+
version (LDC)
149+
return core.math.fabs(f);
150+
else
151+
{
152+
uint tmp = *cast(uint*)&f & 0x7FFF_FFFF;
153+
return *cast(float*)&tmp;
154+
}
145155
}
146156

147157
///
@@ -602,9 +612,14 @@ if (isFloatingPoint!T1 && isFloatingPoint!T2)
602612
return r;
603613
}
604614

615+
pragma(inline, true) // LDC
605616
private real polyImpl(real x, in real[] A) @trusted pure nothrow @nogc
606617
{
607-
version (D_InlineAsm_X86)
618+
version (LDC)
619+
{
620+
return polyImplBase(x, A);
621+
}
622+
else version (D_InlineAsm_X86)
608623
{
609624
if (__ctfe)
610625
{
@@ -954,7 +969,15 @@ if (isFloatingPoint!T)
954969
assert(truncPow2(ulong.min) == 0);
955970

956971
assert(truncPow2(int.max) == (int.max / 2) + 1);
972+
version (LDC)
973+
{
974+
// this test relies on undefined behaviour, i.e. (1 << 63) == int.min
975+
// that fails for LDC with optimizations enabled
976+
}
977+
else
978+
{
957979
assert(truncPow2(int.min) == int.min);
980+
}
958981
assert(truncPow2(long.max) == (long.max / 2) + 1);
959982
assert(truncPow2(long.min) == long.min);
960983
}

std/math/exponential.d

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ import std.traits : isFloatingPoint, isIntegral, isSigned, isUnsigned, Largest,
3737
static import core.math;
3838
static 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+
4055
version (DigitalMars)
4156
{
4257
version = INLINE_YL2X; // x87 has opcodes for these
@@ -45,7 +60,9 @@ version (DigitalMars)
4560
version (D_InlineAsm_X86) version = InlineAsm_X86_Any;
4661
version (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;
4966
version (InlineAsm_X87)
5067
{
5168
static assert(real.mant_dig == 64);
@@ -64,6 +81,17 @@ version (D_HardFloat)
6481
Unqual!F pow(F, G)(F x, G n) @nogc @trusted pure nothrow
6582
if (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+
10361085
pragma(inline, true)
10371086
real 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
10571106
pragma(inline, true)
10581107
float 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+
17431806
pragma(inline, true)
17441807
real 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
17591822
pragma(inline, true)
17601823
float 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+
30413116
real 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+
31413228
real 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+
33023401
real 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

Comments
 (0)