https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91687
Bug ID: 91687 Summary: Fused multiply subtract not generated when same operand appears in multiplication and subtraction. Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: barnaby.wilks at arm dot com Target Milestone: --- Some architectures have instructions that allow the expressions of the form "(x * y) - z" to be done in one instruction (for example the FNMSUB instruction in AArch64). For example float f (float x, float y, float z) { return (y * x) - z; } Will generate f: fnmsub s0, s0, s1, s2 ret This is done with -O2/-O3 with GCC but if -funsafe-math-optimizations are enabled it will convert expressions of the form (x * y) - x to (x - 1) * y which then means that the FNMSUB instruction is not generated. For example on AArch64 trunk (with -O2 -funsafe-math-optimizations) float f (float x, float y) { return (y * x) - y; } will generate f: fmov s2, 1.0e+0 fsub s0, s0, s2 fmul s0, s0, s1 ret whereas if you just compile with (-funsafe-math-optimizations) then the correct code will be generated. f: fnmsub s0, s1, s0, s1 ret This also happens on x86-64. Godbolt demonstrating the problem. https://godbolt.org/z/HuU5LO