TL;DR I added a transformation behind a flag which reassociates some floating point expressions to a form with a shorter arithmetic tree depth: therefore allowing faster execution on cores with multiple arithmetic units. I would like to enable it by default.
In section 10.1.5.2.4 of the 2023 Fortran standard “Evaluation of numerical intrinsic operations”, the standard explicitly allows alternate mathematically equivalent lowerings. For example the source expression X + Y + Z could be evaluated (X + Y) + Z, X + (Y + Z) or even (X + Z) + Y, etc.
The open source benchmark SNBone shows significantly better results with classic flang because classic flang emits real arithmetic expressions in a different order. In the case of this benchmark it reduces dependency depth for instructions issued to the vector unit, allowing for more of the arithmetic to be parallelised over multiple vector execution units.
The lowering added by this transformation tries to mimic the way classic flang orders instructions for these expressions. There is still a notable difference in that classic flang uses FMA intrinsics whereas LLVM Flang relies on the rest of the pipeline to introduce FMA when it is safe to do so.
This is a much less aggressive optimisation than simply enabling reassoc in the fast-math flags because it does not allow reassociation between Fortran language statements (which I do not think would be allowable under the Fortran language standard). Therefore this is distinct from fast-math.
I would like to enable this transformation by default in flang, rather than continuing with our current left to right expression evaluation. I think that doing this is standards compliant, but it could change floating point rounding under some circumstances. I see a few tests in the Fujistu compiler test suite regress with this change due to these rounding changes.
I have tried SPEC2026, SPEC2017, the llvm test suite, the Fujitsu test suite, and a suite of proprietary and open source HPC applications and have not observed any regressions due to these changes, other than the handful of Fujitsu test suite programs noted above which assert exact floating point results.
Does anyone object to this change from always lowering real expressions left-to-right to instead allowing re-association within the expression for optimal code generation?