https://issues.dlang.org/show_bug.cgi?id=22163
--- Comment #1 from Dennis <[email protected]> --- 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. --
