newCTFE Status November 2018
Joakim
dlang at joakim.fea.st
Sun Dec 9 15:23:30 UTC 2018
On Sunday, 9 December 2018 at 14:48:31 UTC, H. S. Teoh wrote:
> On Sat, Dec 08, 2018 at 05:19:59PM +0000, Joakim via
> Digitalmars-d wrote: [...]
>> On Saturday, 8 December 2018 at 15:42:43 UTC, H. S. Teoh wrote:
>> > On Sat, Dec 08, 2018 at 04:06:11AM +0000, Joakim via
>> > Digitalmars-d wrote: [...]
>> > > Btw, do you know some way to get the current compile-time
>> > > real's precision in D code? It would be useful to avoid
>> > > static asserts from overflowing when the runtime real's
>> > > precision exceeds the compile-time real's precision, which
>> > > doesn't happen with dmd but can with ldc:
>> > >
>> > > https://github.com/dlang/phobos/pull/6790#discussion_r238633160
>> >
>> > Doesn't real.dig give the (approximate) precision of real?
>> > Or is
>> > that hard-coded in the frontend?
>>
>> Just so we're clear, the issue is what the precision of reals
>> are when running CTFE code to initialize a constant, as
>> opposed to the precision of the real at runtime. For dmd, this
>> doesn't really matter since it only supports x86/x64 chips,
>> but ldc uses the host's real at compile-time, which can
>> obviously vary from the target. That's why I mentioned to you
>> in another thread that some stdlib math tests assert when
>> cross-compiling from x64 to Android/AArch64, because of that
>> mismatch in host->target precision for reals.
>
> Ahhh, so *that's* the reason for the failure.
Specifically, real.max overflows when it tries to evaluate that
expression, as it tries to stick the 128-bit real.max in the
80-bit x87 real and overflows to Inf, tripping the static assert.
> But I'd think that's more than just a floating-point issue;
> wouldn't CTFE in general be problematic if there's a mismatch
> between host built-in types vs. target built-in types when
> cross-compiling? I suppose D's fixed-sized types help a lot in
> this regard (imagine the mess if `int` varies in size across
> host/target archs -- the kind of mess C/C++ have to deal with).
> But `real` is a fly in the ointment.
Yes, this is called out in the spec:
"Functions executed via CTFE can give different results from run
time in the following scenarios:
- floating point computations may be done at a higher precision
than run time"
https://dlang.org/spec/function.html#interpretation
Of course, that was likely written before we started supporting
64-bit and 128-bit reals, so it was probably assumed that 80-bit
x87 reals would always be used at compile-time and at worst would
be _more_ precise. That's not the case with ldc anymore, since
ldc running on an ARM host will do CTFE at 64-bit precision and
80-bit on an x64 host isn't enough when cross-compiling to
128-bit AArch64 reals.
> I'd imagine difference in endianness would be another cause of
> problems in cross-compilation, though for the most part typical
> D code wouldn't be affected by this at least as far as CTFE is
> concerned (since casting / reinterpretation of unions is not
> currently allowed).
Unsure.
>> real.dig has the same problem as real.mant_dig above, it only
>> gives the target's precision. Compiling this snippet with ldc,
>> `void main() { pragma(msg, "precision is ", real.dig);}`, I
>> get 18 when compiling natively on linux/x64, but 33 when
>> cross-compiling to Android/AArch64, ie it always gives the
>> target real's precision.
>
> Which it should, since any code that depends on real.dig is
> ostensibly expecting the target arch's precision, not the
> host's which may change depending on which host you use to
> compile it.
I tried various other ways before, like checking an enum's
precision or inside a __ctfe block, but they all give the
target's precision, as kinke says, even though they're running at
compile-time.
> Looks like we'll somehow need a way to tell the CTFE engine
> what the target arch should be, and when something doesn't
> match the host type, it should run a software emulation instead
> of using the host's `real`.
Yes, Iain says gdc already uses such multi-precision soft-float,
and kinke mentioned earlier in this thread that he'd like to do
the same with ldc. The reason I brought this issue up is that
Stefan initially mentioned doing something similar for dmd.
More information about the Digitalmars-d
mailing list