Re: [committed] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3.

2020-04-28 Thread Segher Boessenkool
On Sun, Apr 26, 2020 at 10:43:53PM +0200, Iain Buclaw wrote:
>  +// The layout of the type is:
>  +//
>  +//   [1|  7  |   56  ][   8|   56   ]
>  +//   [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ]
>  +//
>  +// We can get the least significant bits by subtracting the 
>  IEEE
>  +// double precision portion from the real value.
> >>>
> >>> That's not correct.  There is no "Unused" field, and the lower fraction
> >>> is not always an immediate extension of the higher fraction.
> >>>
> >>> (It's not 1,7,56 -- it is 1,11,52).

> > All bits are significant to the value, there are no unused bits, for
> > most values.  The sign and exponent of the second number are very much
> > relevant, in general.
> > 
> > I didn't look at your actual implementation, just this comment, but it
> > sounds like your tests miss a lot of cases, if no problems were found?
> 
> All these tests pass.  That is, the computed compile-time byte layout
> (the result of this function) is the same as the layout at run-time.

Then either it tests not nearly enough, or it does not implement what the
comment says.

> // check subnormal storage edge case for Quadruple
> testNumberConvert!("real.min_normal/2UL^^56");
> testNumberConvert!("real.min_normal/19");
> testNumberConvert!("real.min_normal/17");

IBM long double has quite different edge cases than IEEE QP float.

> /**True random values*/
> testNumberConvert!("-0x9.0f7ee55df77618fp-13829L");
> testNumberConvert!("0x7.36e6e2640120d28p+8797L");
> testNumberConvert!("-0x1.05df6ce4702ccf8p+15835L");
> testNumberConvert!("0x9.54bb0d88806f714p-7088L");

None of these are valid double-double numbers (they all underflow or
overflow).

> /**Big overflow or underflow*/
> testNumberConvert!("cast(double)-0x9.0f7ee55df77618fp-13829L");
> testNumberConvert!("cast(double)0x7.36e6e2640120d28p+8797L");
> testNumberConvert!("cast(double)-0x1.05df6ce4702ccf8p+15835L");
> testNumberConvert!("cast(double)0x9.54bb0d88806f714p-7088L");
> testNumberConvert!("cast(float)-0x9.0f7ee55df77618fp-13829L");
> testNumberConvert!("cast(float)0x7.36e6e2640120d28p+8797L");

(Exactly like these).


Segher


Re: [committed] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3.

2020-04-26 Thread Iain Buclaw via Gcc-patches
On 26/04/2020 18:41, Segher Boessenkool wrote:
> On Sun, Apr 26, 2020 at 10:38:57AM +0200, Iain Buclaw wrote:
>> On 25/04/2020 22:50, Segher Boessenkool wrote:
>>> On Sat, Apr 25, 2020 at 02:20:19AM +0200, Iain Buclaw via Gcc-patches wrote:
 +// Parse DoubleDoubles as a pair of doubles.
 +// The layout of the type is:
 +//
 +//   [1|  7  |   56  ][   8|   56   ]
 +//   [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ]
 +//
 +// We can get the least significant bits by subtracting the 
 IEEE
 +// double precision portion from the real value.
>>>
>>> That's not correct.  There is no "Unused" field, and the lower fraction
>>> is not always an immediate extension of the higher fraction.
>>>
>>> (It's not 1,7,56 -- it is 1,11,52).
>>
>> Thanks, I did a quick look-up of where the original might have came
>> from, and I've found another extended floating point format of IBM.
>> I'll send the correction upstream.
>>
>>> A "double double" is really a pair of double precision numbers, both
>>> with sign and exponent fields.  If the first number has maximum
>>> exponent (so, it is infinity or a NaN), the second number is not
>>> significant; otherwise, the sum of the two numbers (taken as exact
>>> numbers, no rounding, no truncation, etc.) is the represented number.
>>> The first number should be that, rounded to double precision.
>>>
>>> So the second double does "add fraction bits" somewhat like this, but
>>> there is an implicit leading 1, for normal numbers, and there can be a
>>> gap between the two halves, too (like in 0x1p0 + 0x1p-100).
>>
>> The job of this routine is to pry out the byte representation of real
>> (long double) values at compile-time for hashing-related purposes.
>>
>> As zero, infinity and NaN are already handled, unless a mismatch between
>> compile and run-time computed hashes is found (I haven't seen any
>> unit-tests trigger failures in the testsuite), I don't think that there
>> is any immediate problem with the current implementation.
>>
>> Thanks for the information though.
> 
> All bits are significant to the value, there are no unused bits, for
> most values.  The sign and exponent of the second number are very much
> relevant, in general.
> 
> I didn't look at your actual implementation, just this comment, but it
> sounds like your tests miss a lot of cases, if no problems were found?
> 

All these tests pass.  That is, the computed compile-time byte layout
(the result of this function) is the same as the layout at run-time.

Don't mind that these are all strings, they are all passed to mixin().

/**Test special values*/
testNumberConvert!("-real.infinity");
testNumberConvert!("real.infinity");
testNumberConvert!("-0.0L");
testNumberConvert!("0.0L");
testNumberConvert!("real.nan");

/**Test min and max values values*/
testNumberConvert!("real.min_normal");
testNumberConvert!("real.max");

/**Test common values*/
testNumberConvert!("-0.17L");
testNumberConvert!("3.14L");

/**Test immutable and const*/
testNumberConvert!("cast(const)3.14L");
testNumberConvert!("cast(immutable)3.14L");

/**Test denormalized values*/
testNumberConvert!("real.min_normal/2");
testNumberConvert!("real.min_normal/2UL^^63");

// check subnormal storage edge case for Quadruple
testNumberConvert!("real.min_normal/2UL^^56");
testNumberConvert!("real.min_normal/19");
testNumberConvert!("real.min_normal/17");

/**Test imaginary values: convert algorithm is same with real values*/
testNumberConvert!("0.0Li");

/**True random values*/
testNumberConvert!("-0x9.0f7ee55df77618fp-13829L");
testNumberConvert!("0x7.36e6e2640120d28p+8797L");
testNumberConvert!("-0x1.05df6ce4702ccf8p+15835L");
testNumberConvert!("0x9.54bb0d88806f714p-7088L");

/**Big overflow or underflow*/
testNumberConvert!("cast(double)-0x9.0f7ee55df77618fp-13829L");
testNumberConvert!("cast(double)0x7.36e6e2640120d28p+8797L");
testNumberConvert!("cast(double)-0x1.05df6ce4702ccf8p+15835L");
testNumberConvert!("cast(double)0x9.54bb0d88806f714p-7088L");
testNumberConvert!("cast(float)-0x9.0f7ee55df77618fp-13829L");
testNumberConvert!("cast(float)0x7.36e6e2640120d28p+8797L");

Iain.


Re: [committed] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3.

2020-04-26 Thread Segher Boessenkool
On Sun, Apr 26, 2020 at 10:38:57AM +0200, Iain Buclaw wrote:
> On 25/04/2020 22:50, Segher Boessenkool wrote:
> > On Sat, Apr 25, 2020 at 02:20:19AM +0200, Iain Buclaw via Gcc-patches wrote:
> >> +// Parse DoubleDoubles as a pair of doubles.
> >> +// The layout of the type is:
> >> +//
> >> +//   [1|  7  |   56  ][   8|   56   ]
> >> +//   [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ]
> >> +//
> >> +// We can get the least significant bits by subtracting the 
> >> IEEE
> >> +// double precision portion from the real value.
> > 
> > That's not correct.  There is no "Unused" field, and the lower fraction
> > is not always an immediate extension of the higher fraction.
> > 
> > (It's not 1,7,56 -- it is 1,11,52).
> 
> Thanks, I did a quick look-up of where the original might have came
> from, and I've found another extended floating point format of IBM.
> I'll send the correction upstream.
> 
> > A "double double" is really a pair of double precision numbers, both
> > with sign and exponent fields.  If the first number has maximum
> > exponent (so, it is infinity or a NaN), the second number is not
> > significant; otherwise, the sum of the two numbers (taken as exact
> > numbers, no rounding, no truncation, etc.) is the represented number.
> > The first number should be that, rounded to double precision.
> > 
> > So the second double does "add fraction bits" somewhat like this, but
> > there is an implicit leading 1, for normal numbers, and there can be a
> > gap between the two halves, too (like in 0x1p0 + 0x1p-100).
> 
> The job of this routine is to pry out the byte representation of real
> (long double) values at compile-time for hashing-related purposes.
> 
> As zero, infinity and NaN are already handled, unless a mismatch between
> compile and run-time computed hashes is found (I haven't seen any
> unit-tests trigger failures in the testsuite), I don't think that there
> is any immediate problem with the current implementation.
> 
> Thanks for the information though.

All bits are significant to the value, there are no unused bits, for
most values.  The sign and exponent of the second number are very much
relevant, in general.

I didn't look at your actual implementation, just this comment, but it
sounds like your tests miss a lot of cases, if no problems were found?


Segher


Re: [committed] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3.

2020-04-26 Thread Iain Buclaw via Gcc-patches
On 25/04/2020 22:50, Segher Boessenkool wrote:
> Hi!
> 
> On Sat, Apr 25, 2020 at 02:20:19AM +0200, Iain Buclaw via Gcc-patches wrote:
>> +// Parse DoubleDoubles as a pair of doubles.
>> +// The layout of the type is:
>> +//
>> +//   [1|  7  |   56  ][   8|   56   ]
>> +//   [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ]
>> +//
>> +// We can get the least significant bits by subtracting the IEEE
>> +// double precision portion from the real value.
> 
> That's not correct.  There is no "Unused" field, and the lower fraction
> is not always an immediate extension of the higher fraction.
> 
> (It's not 1,7,56 -- it is 1,11,52).
> 

Thanks, I did a quick look-up of where the original might have came
from, and I've found another extended floating point format of IBM.
I'll send the correction upstream.


> A "double double" is really a pair of double precision numbers, both
> with sign and exponent fields.  If the first number has maximum
> exponent (so, it is infinity or a NaN), the second number is not
> significant; otherwise, the sum of the two numbers (taken as exact
> numbers, no rounding, no truncation, etc.) is the represented number.
> The first number should be that, rounded to double precision.
> 
> So the second double does "add fraction bits" somewhat like this, but
> there is an implicit leading 1, for normal numbers, and there can be a
> gap between the two halves, too (like in 0x1p0 + 0x1p-100).
> 
> 

The job of this routine is to pry out the byte representation of real
(long double) values at compile-time for hashing-related purposes.

As zero, infinity and NaN are already handled, unless a mismatch between
compile and run-time computed hashes is found (I haven't seen any
unit-tests trigger failures in the testsuite), I don't think that there
is any immediate problem with the current implementation.

Thanks for the information though.

Iain.




Re: [committed] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3.

2020-04-25 Thread Segher Boessenkool
Hi!

On Sat, Apr 25, 2020 at 02:20:19AM +0200, Iain Buclaw via Gcc-patches wrote:
> +// Parse DoubleDoubles as a pair of doubles.
> +// The layout of the type is:
> +//
> +//   [1|  7  |   56  ][   8|   56   ]
> +//   [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ]
> +//
> +// We can get the least significant bits by subtracting the IEEE
> +// double precision portion from the real value.

That's not correct.  There is no "Unused" field, and the lower fraction
is not always an immediate extension of the higher fraction.

(It's not 1,7,56 -- it is 1,11,52).

A "double double" is really a pair of double precision numbers, both
with sign and exponent fields.  If the first number has maximum
exponent (so, it is infinity or a NaN), the second number is not
significant; otherwise, the sum of the two numbers (taken as exact
numbers, no rounding, no truncation, etc.) is the represented number.
The first number should be that, rounded to double precision.

So the second double does "add fraction bits" somewhat like this, but
there is an implicit leading 1, for normal numbers, and there can be a
gap between the two halves, too (like in 0x1p0 + 0x1p-100).


Segher


[committed] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3.

2020-04-24 Thread Iain Buclaw via Gcc-patches
Hi,

This patch merges the D front-end implementation with upstream dmd
09db0c41e, and the D runtime library with upstream druntime e68a5ae3.

* New core.math.toPrec templates have been added as an intrinsic.

  Some floating point algorithms, such as Kahan-Babuska-Neumaier
  Summation, require rounding to specific precisions. Rounding to
  precision after every operation, however, loses overall precision in
  the general case and is a runtime performance problem.

  Adding these functions guarantee the rounding at required points in
  the code, and document where in the algorithm the requirement exists.

* Support IBM long double types in core.internal.convert.

* Add missing aliases for 64-bit vectors in core.simd.

* RUNNABLE_PHOBOS_TEST directive has been properly integrated into the
  D2 language testsuite.

Bootstrapped and regression tested on x86_64-linux-gnu, committed to
mainline.

Regards
Iain

---
gcc/d/ChangeLog:

* intrinsics.cc (expand_intrinsic_toprec): New function.
(maybe_expand_intrinsic): Handle toPrec intrinsics.
* intrinsics.def (TOPRECF, TOPREC, TOPRECL): Add toPrec intrinsics.
---
 gcc/d/dmd/MERGE   |   2 +-
 gcc/d/intrinsics.cc   |  22 +++
 gcc/d/intrinsics.def  |   3 +
 .../gdc.test/compilable/interpret3.d  |  16 ++
 gcc/testsuite/gdc.test/runnable/builtin.d |   2 +-
 gcc/testsuite/gdc.test/runnable/complex.d |   2 +-
 gcc/testsuite/gdc.test/runnable/constfold.d   |   3 +-
 gcc/testsuite/gdc.test/runnable/foreach4.d|   3 +-
 gcc/testsuite/gdc.test/runnable/ifti.d|   2 +-
 gcc/testsuite/gdc.test/runnable/implicit.d|   3 +-
 gcc/testsuite/gdc.test/runnable/inner.d   |   3 +-
 gcc/testsuite/gdc.test/runnable/interpret.d   |  47 -
 gcc/testsuite/gdc.test/runnable/issue8671.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/lazy.d|   2 +-
 gcc/testsuite/gdc.test/runnable/mars1.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/mixin1.d  |   3 +-
 gcc/testsuite/gdc.test/runnable/mixin2.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/s2ir.d|   3 +-
 gcc/testsuite/gdc.test/runnable/stress.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/template4.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/template9.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/test10942.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/test11.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test12.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test12197.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/test15.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test22.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test23.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test24.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test27.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test28.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test34.d  |   3 +-
 gcc/testsuite/gdc.test/runnable/test37.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/test42.d  |   3 +-
 gcc/testsuite/gdc.test/runnable/test5305.d|   2 +-
 gcc/testsuite/gdc.test/runnable/test60.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/testaa.d  |   2 +-
 .../gdc.test/runnable/testbitarray.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/testdstress.d |   2 +-
 gcc/testsuite/gdc.test/runnable/testfile.d|   2 +-
 gcc/testsuite/gdc.test/runnable/testformat.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/testline.d|   2 +-
 gcc/testsuite/gdc.test/runnable/testmmfile.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/testscope2.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/testsignals.d |   2 +-
 gcc/testsuite/gdc.test/runnable/testsocket.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/teststdio.d   |   2 +-
 gcc/testsuite/gdc.test/runnable/testthread2.d |   2 +-
 gcc/testsuite/gdc.test/runnable/testtypeid.d  |   3 +-
 gcc/testsuite/gdc.test/runnable/traits.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/wc.d  |   2 +-
 gcc/testsuite/gdc.test/runnable/wc2.d |   2 +-
 gcc/testsuite/gdc.test/runnable/wc3.d |   2 +-
 gcc/testsuite/gdc.test/runnable/xtest46.d |   2 +-
 gcc/testsuite/gdc.test/runnable/xtest55.d |   2 +-
 libphobos/libdruntime/MERGE   |   2 +-
 libphobos/libdruntime/core/cpuid.d|   2 +-
 libphobos/libdruntime/core/internal/convert.d | 170 --
 libphobos/libdruntime/core/math.d |  71 
 libphobos/libdruntime/core/simd.d |   6 +-
 60 files changed, 329 insertions(+), 121 deletions(-)

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 155286dd765..a878cb9f42e 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-62ce36f3737de691217c21f0173f411734eb1d43
+09db0c41ee922502fa0966bde24c1cb9b15ad436
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index