Bug 4380 – Poor optimisation of x*x, where x is real

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-06-24T03:02:44Z
Last change time
2024-12-13T17:52:25Z
Keywords
backend, performance
Assigned to
No Owner
Creator
Don
Moved to GitHub: dmd#17511 →

Comments

Comment #0 by clugdbug — 2010-06-24T03:02:44Z
// TEST CASE int main(string[] args) { real x = args.length == 2 ? 6.0 : 4.0; // just to defeat the optimiser real y = x*x; return cast(int)y; } ---- With double x, produces: fstp qword ptr [ESP] // store x fld qword ptr [ESP] fmul ST,ST(0) Does the same for float x. With real x, produces fstp tbyte ptr [ESP] // store x fld tbyte ptr [ESP] fld tbyte ptr [ESP] // Why is it loading this twice??? fmulp ST(1),ST The last two lines should just be fmul ST, ST(0)
Comment #1 by hsteoh — 2013-08-17T12:16:37Z
This is still happening on git HEAD.
Comment #2 by yebblies — 2013-08-17T21:02:45Z
In cg87, line 1661 (load87) it has this code: if ((ty == TYldouble || ty == TYildouble) && op != -1 && e->Eoper != OPd_ld) goto Ldefault; op is 0 here (OPvar), and ty == TYldouble, so all the normal var cse checking is skipped. Down at 1887, we have #if 1 /* Do this instead of codelem() to avoid the freenode(e). We also lose CSE capability */ if (e->Eoper == OPconst) { c = load87(e, 0, &retregs, NULL, -1); } else c = (*cdxxx[e->Eoper])(e,&retregs); #else c = codelem(e,&retregs,FALSE); #endif So it looks like this was intentional to avoid some kind of compiler internal bug. Removing both conditions results in the correct code, but who knows what else it breaks.
Comment #3 by dmitry.olsh — 2018-05-17T14:54:44Z
Still a problem in DMD 2.080
Comment #4 by robert.schadek — 2024-12-13T17:52:25Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17511 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB