Skip to content

Comment on Why doesn't GCC optimize a*a*a*a*a*a to (a*a*a)*(a*a*a)? (2013)parent

Comments

As the answer on stackoverflow mentions, there is -ffast-math option to gcc that tells the compiler to treat fp operations as associative. I've done some testing:

  $ clang -v
  clang version 3.3 (tags/RELEASE_33/final)
  Target: x86_64-apple-darwin12.4.0

  double pow(double);
  
        LLVM bitcode                   Assembly

  // a*a*a*a*a*a                 
  %1 = fmul double %a, %a       |  movaps %xmm0, %xmm1
  %2 = fmul double %1, %a       |  mulsd  %xmm1, %xmm1
  %3 = fmul double %2, %a       |  mulsd  %xmm0, %xmm1
  %4 = fmul double %3, %a       |  mulsd  %xmm0, %xmm1
  %5 = fmul double %4, %a       |  mulsd  %xmm0, %xmm1
  ret double %5                 |  mulsd  %xmm0, %xmm1
                                |  movaps %xmm1, %xmm0

  // a*a*a*a*a*a -ffast-math    
  %1 = fmul fast double %a, %a  |  mulsd  %xmm0, %xmm0
  %2 = fmul fast double %1, %1  |  movaps %xmm0, %xmm1
  %3 = fmul fast double %1, %2  |  mulsd  %xmm1, %xmm1
  ret double %3                 |  mulsd  %xmm0, %xmm1
                                |  movaps %xmm1, %xmm0

  // (a*a*a)*(a*a*a)            
  %1 = fmul fast double %a, %a  |  movaps %xmm0, %xmm1
  %2 = fmul fast double %1, %a  |  mulsd  %xmm0, %xmm0
  %3 = fmul fast double %2, %2  |  mulsd  %xmm1, %xmm0
  ret double %3                 |  mulsd  %xmm0, %xmm0

I wrote GCC's reassociation pass.

LLVM and GCC use the same algorithm for reassociation (and as far as i know, there is still no good literature on tradeoffs one way or the other), so you will get the same results, modulo some small differences implementation differences.

The reassociation passes exist mainly to promote redundancy elimination, and so the factorizations they perform are tilted towards making binary operations that look the same. Factorization and transformation into pow calls is also done, but this is just because it's easy to do :)

Note that the operations it forms may be "less than ideal" from a register pressure perspective, since it does not take this into account at the level reassociation is being performed (it assumes something will later reassociate them some other way if it wishes).

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.