www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Overly clever constant folding

reply John Colvin <john.loughran.colvin gmail.com> writes:
Is this the "constant fold at higher precision and break all your 
IEEE-754 expectations" madness again? Or something else?

```
void main()
{
     auto a = long.min;
     auto b = long.max;
     auto c = 0.0;
     writeln((long.min + long.max) + 0.0); // -1
     writeln(long.min + (long.max + 0.0)); // -1
     writeln(long.min + cast(double)(long.max)); // -1
     writeln((a + b) + c); // -1
     writeln(a + (b + c)); // 0
     writeln(a + cast(double)(b)); // 0
}
```

Hint for those confused: the nearest double to long.max is one 
greater than long.max

The 3rd one is particularly awful.
Dec 10 2022
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
You know what's coming - please file a bugzilla issue!
Dec 10 2022
parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On Saturday, 10 December 2022 at 23:00:28 UTC, Walter Bright 
wrote:
 You know what's coming - please file a bugzilla issue!
No bug needed for D, as it was decided what to do wrt CTFE floating point in 2012. ImportC is affected though: https://issues.dlang.org/show_bug.cgi?id=23550
Dec 11 2022
prev sibling next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On Saturday, 10 December 2022 at 21:36:42 UTC, John Colvin wrote:
 Is this the "constant fold at higher precision and break all 
 your IEEE-754 expectations" madness again? Or something else?
--snip--
 Hint for those confused: the nearest double to long.max is one 
 greater than long.max

 The 3rd one is particularly awful.
This is exactly what core.math.toPrec was made for. ``` import core.math; writeln((long.min + long.max) + 0.0); // -1 writeln(long.min + toPrec!double(long.max + 0.0)); // 0 writeln(long.min + toPrec!double(long.max)); // 0 ```
Dec 11 2022
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Saturday, 10 December 2022 at 21:36:42 UTC, John Colvin wrote:
 Is this the "constant fold at higher precision and break all 
 your IEEE-754 expectations" madness again? Or something else?

 [...]
It really isn't. The problem stem from DMD using real precision when doing constant folding in the frontend, without rounding intermediary results. This behavior is not correct according to floating points, and means that any change in the way DMD constant fold in the frontend can change the semantic of the program. While fixing this after a bug report is dully provided, is certainly a path forward, it would be missing the larger point: why is constant folding done there to begin with? This leads to all kind of strange and bizarre behaviors, such as making it very unpredictable when the compiler will yell at you about unreachable code. Today's optimizer are shockingly good at doing this kind of transformations, and duplicating the logic between the optimizer and the front will *in the ideal case* multiply the umber of bugs by two, but in practice much more, because DMD is not and probably never will be battle tested to the degree LLVM or GCC are. And if take a step back to the step back, we notice that this is where the "fill a bug report" approach fails. While this approach will certainly help fix this one specific issue, it doesn't address the larger point that make this kind of issue - and many others - more likely to occur. In fact, piling up more and more complex logic under the wrong structure makes it harder and harder to replace with a newer, more sensible one. Anyways, we need to stop constant folding in the front end, and, while we are at it, we should also stop inlining in there.
Dec 11 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 12/11/2022 12:39 PM, deadalnix wrote:
 why is constant folding done 
 there to begin with?
How else are you going to have, for example, a static initializer initialized with an expression? How about `static if (expression)` ? How can you do optimization without constant folding?
 Today's optimizer are shockingly good at doing this kind of transformations
The optimizer is doing the constant folding.
 And if take a step back to the step back, we notice that this is where the
"fill 
 a bug report" approach fails.
Not filing a bug report means the bug will never get fixed. The n.g. is not a practical bug reporting system (I know, I tried it in the early days of D).
 we should also stop inlining in there.
I do agree with that. In fact, I implemented it: https://github.com/dlang/dmd/blob/master/compiler/src/dmd/backend/inliner.d
Dec 11 2022
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/12/22 03:13, Walter Bright wrote:
 On 12/11/2022 12:39 PM, deadalnix wrote:
 why is constant folding done there to begin with?
How else are you going to have, for example, a static initializer initialized with an expression? How about `static if (expression)` ? How can you do optimization without constant folding?
I think his proposal was not to stop doing it altogether but to instead do a roundtrip through the backend for constant folding. (I guess SDC is doing CTFE by jitting with LLVM.)
Dec 12 2022