title: GCC 6.3.1 doesn't autovectorize without -ffinite-math-only
body: <p>I would like to understand why GCC does not autovectorize the following loop, unless I pass the -ffinite-math-only. As to my understanding and the GCC manual the optimization requires the <code>-funsafe-math-optimizations</code></p>
  
  <blockquote>
    <p>If the selected floating-point hardware includes the NEON extension (e.g. -mfpu=neon), note that floating-point operations are not generated by GCC's auto-vectorization pass unless -funsafe-math-optimizations is also specified.  This is because NEON
               hardware does not fully implement the IEEE 754 standard for floating-point arithmetic (in particular denormal values are treated as zero), so the use of NEON instructions may lead to a loss of precision.</p>
  </blockquote>
  
  <p>In particular, the flag enables the compiler to assume associative math, so that it can first accumulate with 4 partial sums. The code seems pretty straight forward</p>
  
  <pre><code>template&lt;typename SumType = double&gt;
  class UipLineResult {
  public:
     SumType sqsum;
     SumType dcsum;
     float pkp;
     float pkn;
  
  public:
     UipLineResult() {
        clear();
     }
  
     void clear() {
        sqsum = 0;
        dcsum = 0;
        pkp = -std::numeric_limits&lt;float&gt;::max();
        pkn = +std::numeric_limits&lt;float&gt;::max();
     }
  };
  </code></pre>
  
  <p>Loop that is not vectorized</p>
  
  <pre><code>static void addSamplesLine(const float* ss, UipLineResult&lt;&gt;* line) {
     UipLineResult&lt;float&gt; intermediate;
     for(int idx = 0; idx &lt; 120; idx++) {
        float s = ss[idx];
        intermediate.sqsum += s * s;
        intermediate.dcsum += s;
        intermediate.pkp = intermediate.pkp &lt; s ? s : intermediate.pkp;
        intermediate.pkn = intermediate.pkn &gt; s ? s : intermediate.pkn;
     }
     line-&gt;addIntermediate(&amp;intermediate);
  }
  </code></pre>
  
  <p>For example, the squared addition look like</p>
  
  <pre><code>      intermediate.sqsum += s * s;
  107da:       ee47 6aa7       vmla.f32        s13, s15, s15
  </code></pre>
  
  <p>With <code>-ffinite-math-only</code> this becomes</p>
  
  <pre><code>      intermediate.sqsum += s * s;
  1054c:       ef40 6df0       vmla.f32        q11, q8, q8
  </code></pre>
  
  <p>Compiler flags</p>
  
  <blockquote>
    <p>-funsafe-math-optimizations -ffinite-math-only -mcpu=cortex-a9 -mfpu=neon</p>
  </blockquote>