| |
| Posted by Timon Gehr in reply to Walter Bright | PermalinkReply |
|
Timon Gehr
Posted in reply to Walter Bright
| On 14.02.24 05:49, Walter Bright wrote:
> On 2/12/2024 7:31 PM, Richard (Rikki) Andrew Cattermole wrote:
>> dmd having bad codegen here isn't a surprise, that is to be expected.
>
> I'm used to people saying that DMD doesn't do data flow analysis. It does. In fact, it is based on my OptimumC, which was the first C compiler on DOS to do DFA back in the 1980s.
>
> This isn't a case of buggy DFA. It's a case of doing DFA correctly.
>
> The issue is pointer aliasing. A pointer can point to anything, including const data. Therefore, storing through a pointer can alter any value that is reachable via a pointer. Therefore, storing through a pointer invalidates any cached value already read.
>
> This is what you're seeing.
> ...
Well, my understanding is that storing a value that was read from a `uint*` cannot invalidate a value read from the same `uint*` unless unaligned reads/writes are allowed or the pointer can point to itself.
Are unaligned reads/writes allowed in D? Can a `uint*` point to itself? Is there something else I missed?
How to make the following assertion fail by filling the `...` holes with code without invoking UB?
```d
void fillBP1(uint* value, uint* dest)pure{
dest[0] = *value;
dest[1] = *value;
dest[2] = *value;
dest[3] = *value;
}
void fillBP2(uint* value, uint* dest)pure{
auto tmp = *value;
dest[0] = tmp;
dest[1] = tmp;
dest[2] = tmp;
dest[3] = tmp;
}
uint[4] distinguish(alias f)()pure{
...; // TODO
uint[4] dest = ...; // TODO
uint* value = ...; // TODO
f(value,dest.ptr);
return dest;
}
void main(){
import std.stdio;
assert(distinguish!fillBP1()==distinguish!fillBP2());
writeln(test!fillBP1);
writeln(test!fillBP2);
}
```
> C99 tried to address this with __restrict, but few people use it or understand it. D didn't bother with it because people will inevitably misuse __restrict and get their data mysteriously corrupted.
>
My understanding is the case in the OB does not require `__restrict`. `value` can point to any of the 4 fields of `dest`, it is okay to only read it once even in that case. Of course, maybe the data flow analysis is more conservative than that, but I wouldn't necessarily point to this case as one where data flow analysis is working "correctly".
|