aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std/math/hardware.d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-12-09 18:59:38 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2022-12-11 17:17:58 +0100
commit6d799f0aed18be25a5c908499b6411ab6d06b78c (patch)
tree3e6a91048c7fe3e78bae9f75b24eb37c5504681b /libphobos/src/std/math/hardware.d
parentcc7f509d3c0b3ab63891cf7ca2def0fdfb3642c4 (diff)
downloadgcc-6d799f0aed18be25a5c908499b6411ab6d06b78c.zip
gcc-6d799f0aed18be25a5c908499b6411ab6d06b78c.tar.gz
gcc-6d799f0aed18be25a5c908499b6411ab6d06b78c.tar.bz2
d: Merge upstream dmd, druntime c8ae4adb2e, phobos 792c8b7c1.
D front-end changes: - Import dmd v2.101.0. - Deprecate the ability to call `__traits(getAttributes)' on overload sets. - Deprecate non-empty `for' statement increment clause with no effect. - Array literals assigned to `scope' array variables can now be allocated on the stack. D runtime changes: - Import druntime v2.101.0. Phobos changes: - Import phobos v2.101.0. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd c8ae4adb2e. * typeinfo.cc (check_typeinfo_type): Update for new front-end interface. (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Remove warning that toHash() must be declared 'nothrow @safe`. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime c8ae4adb2e. * src/MERGE: Merge upstream phobos 792c8b7c1.
Diffstat (limited to 'libphobos/src/std/math/hardware.d')
-rw-r--r--libphobos/src/std/math/hardware.d124
1 files changed, 78 insertions, 46 deletions
diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d
index 40e42da..81c7302 100644
--- a/libphobos/src/std/math/hardware.d
+++ b/libphobos/src/std/math/hardware.d
@@ -37,13 +37,6 @@ version (RISCV64) version = RISCV_Any;
version (D_InlineAsm_X86) version = InlineAsm_X86_Any;
version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
-version (InlineAsm_X86_Any) version = InlineAsm_X87;
-version (InlineAsm_X87)
-{
- static assert(real.mant_dig == 64);
- version (CRuntime_Microsoft) version = InlineAsm_X87_MSVC;
-}
-
version (X86_64) version = StaticallyHaveSSE;
version (X86) version (OSX) version = StaticallyHaveSSE;
@@ -76,19 +69,6 @@ version (D_HardFloat)
version (IeeeFlagsSupport) version = FloatingPointControlSupport;
}
-version (GNU)
-{
- // The compiler can unexpectedly rearrange floating point operations and
- // access to the floating point status flags when optimizing. This means
- // ieeeFlags tests cannot be reliably checked in optimized code.
- // See https://github.com/ldc-developers/ldc/issues/888
-}
-else
-{
- version = IeeeFlagsUnittest;
- version = FloatingPointControlUnittest;
-}
-
version (IeeeFlagsSupport)
{
@@ -368,7 +348,7 @@ public:
}
///
-version (IeeeFlagsUnittest)
+version (StdDdoc)
@safe unittest
{
import std.math.traits : isNaN;
@@ -376,17 +356,14 @@ version (IeeeFlagsUnittest)
static void func() {
int a = 10 * 10;
}
- pragma(inline, false) static void blockopt(ref real x) {}
real a = 3.5;
// Set all the flags to zero
resetIeeeFlags();
assert(!ieeeFlags.divByZero);
- blockopt(a); // avoid constant propagation by the optimizer
// Perform a division by zero.
a /= 0.0L;
assert(a == real.infinity);
assert(ieeeFlags.divByZero);
- blockopt(a); // avoid constant propagation by the optimizer
// Create a NaN
a *= 0.0L;
assert(ieeeFlags.invalid);
@@ -399,7 +376,33 @@ version (IeeeFlagsUnittest)
assert(ieeeFlags == f);
}
-version (IeeeFlagsUnittest)
+@safe unittest
+{
+ import std.math.traits : isNaN;
+
+ static void func() {
+ int a = 10 * 10;
+ }
+ real a = 3.5;
+ // Set all the flags to zero
+ resetIeeeFlags();
+ assert(!ieeeFlags.divByZero);
+ // Perform a division by zero.
+ a = forceDivOp(a, 0.0L);
+ assert(a == real.infinity);
+ assert(ieeeFlags.divByZero);
+ // Create a NaN
+ a = forceMulOp(a, 0.0L);
+ assert(ieeeFlags.invalid);
+ assert(isNaN(a));
+
+ // Check that calling func() has no effect on the
+ // status flags.
+ IeeeFlags f = ieeeFlags;
+ func();
+ assert(ieeeFlags == f);
+}
+
@safe unittest
{
import std.meta : AliasSeq;
@@ -412,27 +415,26 @@ version (IeeeFlagsUnittest)
static foreach (T; AliasSeq!(float, double, real))
{{
- T x; /* Needs to be here to trick -O. It would optimize away the
- calculations if x were local to the function literals. */
+ T x; // Needs to be here to avoid `call without side effects` warning.
auto tests = [
Test(
- () { x = 1; x += 0.1L; },
+ () { x = forceAddOp!T(1, 0.1L); },
() => ieeeFlags.inexact
),
Test(
- () { x = T.min_normal; x /= T.max; },
+ () { x = forceDivOp!T(T.min_normal, T.max); },
() => ieeeFlags.underflow
),
Test(
- () { x = T.max; x += T.max; },
+ () { x = forceAddOp!T(T.max, T.max); },
() => ieeeFlags.overflow
),
Test(
- () { x = 1; x /= 0; },
+ () { x = forceDivOp!T(1, 0); },
() => ieeeFlags.divByZero
),
Test(
- () { x = 0; x /= 0; },
+ () { x = forceDivOp!T(0, 0); },
() => ieeeFlags.invalid
)
];
@@ -453,14 +455,24 @@ void resetIeeeFlags() @trusted nothrow @nogc
}
///
+version (StdDdoc)
@safe unittest
{
- pragma(inline, false) static void blockopt(ref real x) {}
resetIeeeFlags();
real a = 3.5;
- blockopt(a); // avoid constant propagation by the optimizer
a /= 0.0L;
- blockopt(a); // avoid constant propagation by the optimizer
+ assert(a == real.infinity);
+ assert(ieeeFlags.divByZero);
+
+ resetIeeeFlags();
+ assert(!ieeeFlags.divByZero);
+}
+
+@safe unittest
+{
+ resetIeeeFlags();
+ real a = 3.5;
+ a = forceDivOp(a, 0.0L);
assert(a == real.infinity);
assert(ieeeFlags.divByZero);
@@ -475,25 +487,39 @@ void resetIeeeFlags() @trusted nothrow @nogc
}
///
+version (StdDdoc)
@safe nothrow unittest
{
import std.math.traits : isNaN;
- pragma(inline, false) static void blockopt(ref real x) {}
resetIeeeFlags();
real a = 3.5;
- blockopt(a); // avoid constant propagation by the optimizer
a /= 0.0L;
assert(a == real.infinity);
assert(ieeeFlags.divByZero);
- blockopt(a); // avoid constant propagation by the optimizer
a *= 0.0L;
assert(isNaN(a));
assert(ieeeFlags.invalid);
}
+@safe nothrow unittest
+{
+ import std.math.traits : isNaN;
+
+ resetIeeeFlags();
+ real a = 3.5;
+
+ a = forceDivOp(a, 0.0L);
+ assert(a == real.infinity);
+ assert(ieeeFlags.divByZero);
+
+ a = forceMulOp(a, 0.0L);
+ assert(isNaN(a));
+ assert(ieeeFlags.invalid);
+}
+
} // IeeeFlagsSupport
@@ -1100,7 +1126,6 @@ private:
}
///
-version (FloatingPointControlUnittest)
@safe unittest
{
import std.math.rounding : lrint;
@@ -1154,32 +1179,27 @@ version (FloatingPointControlUnittest)
ensureDefaults();
}
-version (FloatingPointControlUnittest)
@safe unittest // rounding
{
import std.meta : AliasSeq;
static T addRound(T)(uint rm)
{
- pragma(inline, false) static void blockopt(ref T x) {}
pragma(inline, false);
FloatingPointControl fpctrl;
fpctrl.rounding = rm;
T x = 1;
- blockopt(x); // avoid constant propagation by the optimizer
- x += 0.1L;
+ x = forceAddOp(x, 0.1L);
return x;
}
static T subRound(T)(uint rm)
{
- pragma(inline, false) static void blockopt(ref T x) {}
pragma(inline, false);
FloatingPointControl fpctrl;
fpctrl.rounding = rm;
T x = -1;
- blockopt(x); // avoid constant propagation by the optimizer
- x -= 0.1L;
+ x = forceSubOp(x, 0.1L);
return x;
}
@@ -1210,4 +1230,16 @@ version (FloatingPointControlUnittest)
}}
}
+} // FloatingPointControlSupport
+
+version (StdUnittest)
+{
+ // These helpers are intended to avoid constant propagation by the optimizer.
+ pragma(inline, false) private @safe
+ {
+ T forceAddOp(T)(T x, T y) { return x + y; }
+ T forceSubOp(T)(T x, T y) { return x - y; }
+ T forceMulOp(T)(T x, T y) { return x * y; }
+ T forceDivOp(T)(T x, T y) { return x / y; }
+ }
}