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: > 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. 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