Bug 22163 – [REG 2.094.0] wrong code with static float array and delegate accessing it
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2021-08-01T14:51:43Z
Last change time
2022-01-14T13:44:17Z
Keywords
backend, pull, wrong-code
Assigned to
No Owner
Creator
Dennis
Comments
Comment #0 by dkorpel — 2021-08-01T14:51:43Z
Reduced code:
```
import core.stdc.stdio;
void drawText(float[2] size) {
printf("%f %f\n", size[0], size[1]);
scope dg = (int x) => size[0];
}
extern(C) void main() {
float[2] size = [10.0, 20.0];
printf("%f %f\n", size[0], size[1]);
drawText(size);
}
```
Prints:
10.000000 20.000000
10.000000 0.000000
It should print 20 instead of 0 for `size[1]` the second time. It works with LDC, so I assume it's a backend / glue code bug. It also works on Windows, or when replacing `float` with `int`, or without the delegate.
Comment #1 by dkorpel — 2021-08-02T10:09:24Z
So far I found out that the delegate makes the parameter volatile in dmd/tocsym.d:
```
if (vd.nestedrefs.dim)
{
/* Symbol is accessed by a nested function. Make sure
* it is not put in a register, and that the optimizer
* assumes it is modified across function calls and pointer
* dereferences.
*/
//printf("\tnested ref, not register\n");
type_setcv(&t, t.Tty | mTYvolatile);
}
```
Then in dmd/backend/cod1.d:FuncParamRegs_alloc the float[2] is combined into the xmm0 register:
```
if (tyaggregate(ty))
{
/* ... */
else if (tybasic(t.Tty) == TYarray)
{
if (I64)
argtypes(t, targ1, targ2);
}
```
But in dmd/backend/cod3.d:prolog_loadparams this branch isn't taken:
```
// This logic is same as FuncParamRegs_alloc function at src/dmd/backend/cod1.d
//
// Find suitable SROA based on the element type
// (Don't put volatile parameters in registers)
if (tyb == TYarray && !(t.Tty & mTYvolatile))
{
type *targ1;
argtypes(t, targ1, t2);
if (targ1)
t = targ1;
}
```
Which makes it load a `double` from xmm0 instead of a `float`. The comment "This logic is same as FuncParamRegs_alloc function" is no longer true, but I'm not certain what the fix is. I doubt `volatile` should affect the abi, but "Don't put volatile parameters in registers" was written for a reason so I don't want to remove that without consideration.
Comment #2 by dlang-bot — 2021-11-02T14:45:54Z
@dkorpel created dlang/dmd pull request #13256 "Fix issue 22163 - wrong code with static float array and delegate accessing it" fixing this issue:
- Fix issue 22163 - wrong code with static float array and delegate accessing it
https://github.com/dlang/dmd/pull/13256
Comment #3 by dkorpel — 2021-12-13T13:03:48Z
*** Issue 22588 has been marked as a duplicate of this issue. ***
Comment #4 by dlang-bot — 2022-01-14T13:44:17Z
dlang/dmd pull request #13256 "Fix issue 22163 - wrong code with static float array and delegate accessing it" was merged into stable:
- 78d2e0833d21680de1090ad3d3fd68dd3205739e by dkorpel:
Fix issue 22163 - wrong code with static float array and delegate accessing it
https://github.com/dlang/dmd/pull/13256