diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-12-09 18:59:38 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-12-11 17:17:58 +0100 |
commit | 6d799f0aed18be25a5c908499b6411ab6d06b78c (patch) | |
tree | 3e6a91048c7fe3e78bae9f75b24eb37c5504681b /libphobos/src/std/math/hardware.d | |
parent | cc7f509d3c0b3ab63891cf7ca2def0fdfb3642c4 (diff) | |
download | gcc-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.d | 124 |
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; } + } } |