[Bug middle-end/91687] New: Fused multiply subtract not generated when same operand appears in multiplication and subtraction.
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: fmovs2, 1.0e+0 fsubs0, s0, s2 fmuls0, 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
[Bug middle-end/91687] Fused multiply subtract not generated when same operand appears in multiplication and subtraction.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91687 --- Comment #1 from barnaby.wilks at arm dot com --- (In reply to barnaby.wilks from comment #0) > 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: > fmovs2, 1.0e+0 > fsubs0, s0, s2 > fmuls0, s0, s1 > ret > > whereas if you just compile with (-funsafe-math-optimizations) then the > correct > code will be generated. Ah, wrote the wrong thing :D Here it should say > whereas if you just compile with -O2 then the > correct code will be generated. The problem only occurs with -funsafe-math-optimizations. > f: > fnmsub s0, s1, s0, s1 > ret > > This also happens on x86-64. > > Godbolt demonstrating the problem. > https://godbolt.org/z/HuU5LO