https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90427

            Bug ID: 90427
           Summary: missing "sign flipping" optimization
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tromey at gcc dot gnu.org
  Target Milestone: ---

This test case comes from this blog post:
https://nfrechette.github.io/2019/05/08/sign_flip_optimization/
(which also says that clang 8 performs this optimization).

Consider

float foo_ref(float value) {
  value = value * 0.5f;   // mulss value, 0.5f
                          // movss tmp, 1.0f
  return 1.0f - value;    // subss tmp, value
}

float foo_ref2(float value) {
  value = value * -0.5f;  // mulss value, -0.5f
  return value + 1.0f; // addss value, 1.0f
}


According to the post, these are equivalent.  However, gcc
generates different code for them, with the latter being better.

The comments for the first function seem to omit an
instruction that gcc emits, making that version even worse:

        movss   .LC0(%rip), %xmm1
        mulss   %xmm0, %xmm1
        movss   .LC1(%rip), %xmm0
        subss   %xmm1, %xmm0

However the comments in the second one are correct:

        mulss   .LC2(%rip), %xmm0
        addss   .LC1(%rip), %xmm0


Tested with git master from today, using gcc -O2, on x86-64 Fedora 29.

I just made a guess at which component to use.

Reply via email to