[Bug middle-end/91687] New: Fused multiply subtract not generated when same operand appears in multiplication and subtraction.

barnaby.wilks at arm dot com gcc-bugzilla@gcc.gnu.org
Fri Sep 6 15:50:00 GMT 2019


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


More information about the Gcc-bugs mailing list