Bug #82760 Do not use -fno-expensive-optimizations just to avoid fused madd instructions
Submitted: 28 Aug 2016 12:45 Modified: 25 Oct 2016 14:04
Reporter: Alexey Kopytov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Compiling Severity:S3 (Non-critical)
Version:5.7.14 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[28 Aug 2016 12:45] Alexey Kopytov
Description:
The following commit introduced in 5.7.14 adds
-fno-expensive-optimizations to GCC options on some platforms:

commit 1919ed695a28905c40d4cc8dfd9d24db6c879f3d
Author: Norvald H. Ryeng <norvald.ryeng@oracle.com>
Date:   Fri May 27 15:19:56 2016 +0200

    Bug#23046775 DIFFERENT FLOATING POINT RESULTS ON ARM64 AND POWERPC
    
    Backport from trunk.
    
    Problem: The -fexpensive-optimizations option to gcc causes ARM64 and
    PowerPC build to compute floating point operations slightly
    differently from other platforms. This flag is enabled by -O2 and
    higher optimization levels.
    
    Fix: Check for the unwanted floating point behavior in CMake and
    disable expensive-optimizations in GCC builds on platforms that
    experience this behavior.

I believe the real reason for results difference in some floating point
calculations is fused multiply-add instructions that are available on
certain CPU architectures:
https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation#Fused_multiply.E2.80.9...

Note that the list of architectures where FMA instructions are supported is not
limited to ARM64 and PowerPC. It is also available on recent x86_64
CPUs. I first encountered this problem with IA64 CPUs when I was
revisiting floating point support in MySQL 5.1.

The only way to ensure uniform FP calculations across all architectures
is to disable usage of FMA instructions. However, the way it was
implemented looks questionable to me: adding
-fno-expensive-optimizations to compiler flags would also disable other,
possibly important optimizations.

Ideally one should use the -mno-fused-madd GCC option. Unfortunately,
it's architecture-dependent, and not available on some
architectures. For example, it is available on IA64 and PowerPC, but not
on AArch64.

There's also -ffp-contract=off which has a similar effect, is less
restrictive than -fno-expensive-optimizations and available on all
architectures and old enough GCC versions. I have verified it fixes the
original problem solved with -fno-expensive-optimizations in the above
commit (as in, the corresponding CMake test passes).

I'm going to submit a patch replacing -fno-expensive-optimizations with
-ffp-contract=off.

How to repeat:
Look at commit 1919ed69. Read the description of
-fno-expensive-optimizations in the GCC manual.

Suggested fix:
Use -ffp-contract=off instead of -fno-expensive-optimizations.
[30 Aug 2016 16:17] OCA Admin
Contribution submitted via Github - Bug #82760: Do not use -fno-expensive-optimizations just to avoid fused madd ins 
(*) Contribution by Alexey Kopytov (Github akopytov, mysql-server/pull/92#issuecomment-243105786): I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: git_patch_83015395.txt (text/plain), 7.19 KiB.

[31 Aug 2016 11:09] Umesh Shastry
Hello Alexey,

Thank you for the report and contribution.

Thanks,
Umesh
[25 Oct 2016 14:04] Paul Dubois
Posted by developer:
 
Noted in 5.7.17, 8.0.1 changelogs.

For GCC versions higher than 4.4, -fno-expensive-optimizations was
replaced with -ffp-contract=off, which has the effect of enabling
more optimizations. Thanks to Alexey Kopytov for the patch.