title: Why can GCC not vectorize this function and loop?
body: <p>I'm attempting to make a function SIMD-enabled and vectorize the loop with a function call.</p>
  
  <pre><code>#include &lt;cmath&gt;
  
  #pragma omp declare simd
  double BlackBoxFunction(const double x) {
      return 1.0/sqrt(x);
  }
  
  double ComputeIntegral(const int n, const double a, const double b) {
      const double dx = (b - a)/n;
      double I = 0.0;
      #pragma omp simd reduction(+: I)
  
      for (int i = 0; i &lt; n; i++) {
        const double xip12 = a + dx*(double(i) + 0.5);
        const double yip12 = BlackBoxFunction(xip12);
        const double dI = yip12*dx;
        I += dI; 
    }
    return I;
  }
  </code></pre>
  
  <p>For the code above, if I compile it with <code>icpc</code>:</p>
  
  <pre><code>icpc worker.cc -qopenmp -qopt-report=5 -c
  </code></pre>
  
  <p>The opt-report shows that the function and loop are both vectorized.
  However, if I try to compile it with <code>g++ 6.5</code>:</p>
  
  <pre><code>g++ worker.cc -O3 -fopenmp -fopt-info-vec-missed -funsafe-math-optimizations -c
  </code></pre>
  
  <p>The output shows <code>note:not vectorized: control flow in loop.</code> and <code>note: bad loop form</code>, and the loop cannot be vectorized.</p>
  
  <p>How can I vectorize the loop with GCC?</p>
  
  <p><strong>EDIT :</strong></p>
  
  <p>If I write the function into a separate file,</p>
  
  <p><code>worker.cc</code>:</p>
  
  <pre><code>#include "library.h"
  
  double ComputeIntegral(const int n, const double a, const double b) {
      const double dx = (b - a)/n;
      double I = 0.0;
      #pragma omp simd reduction(+: I)
  
      for (int i = 0; i &lt; n; i++) {
        const double xip12 = a + dx*(double(i) + 0.5);
        const double yip12 = BlackBoxFunction(xip12);
        const double dI = yip12*dx;
        I += dI; 
    }
    return I;
  }
  </code></pre>
  
  <p><code>library.h</code>:</p>
  
  <pre><code>#ifndef __INCLUDED_LIBRARY_H__
  #define __INCLUDED_LIBRARY_H__
  
  #pragma omp declare simd
  double BlackBoxFunction(const double x); 
  
  #endif
  </code></pre>
  
  <p>and <code>library.cc</code>:</p>
  
  <pre><code>#include &lt;cmath&gt;
  
  #pragma omp declare simd
  double BlackBoxFunction(const double x) {
    return 1.0/sqrt(x);
  }
  </code></pre>
  
  <p>Then I compile it with GCC:</p>
  
  <pre><code>g++ worker.cc library.cc -O3 -fopenmp -fopt-info-vec-missed -funsafe-math-optimizations -c
  </code></pre>
  
  <p>It shows:</p>
  
  <pre><code>worker.cc:9:31: note: loop vectorized
  </code></pre>
  
  <p>but </p>
  
  <pre><code>library.cc:5:18: note:not vectorized: control flow in loop.
  library.cc:5:18: note:bad loop form.
  </code></pre>
  
  <p>It makes me confused. I wonder whether it is already vectorized.</p>