title: Why Does This Auto-Vectorizer Care About Constructors/Destructors?
body: <p>Here is a <a href="http://sscce.org/" rel="noreferrer">SSCCE</a>:</p>
  
  <pre><code>class Vec final {
      public:
          float data[4];
  
          inline Vec(void) {}
          inline ~Vec(void) {}
  };
  Vec operator*(float const&amp; scalar, Vec const&amp; vec) {
      Vec result;
      #if 1
          for (int k=0;k&lt;4;++k) result.data[k]=scalar*vec.data[k];
      #else
          float const*__restrict src =    vec.data;
          float      *__restrict dst = result.data;
          for (int k=0;k&lt;4;++k) dst[k]=scalar*src[k];
      #endif
      return result;
  }
  
  int main(int /*argc*/, char* /*argv*/[]) {
      Vec vec;
      Vec scaledf = 2.0f * vec;
      return 0;
  }
  </code></pre>
  
  <hr>
  
  <p>When compiling, MSVC 2013 informs me (<code>/Qvec-report:2</code>) that</p>
  
  <blockquote>
    <p>main.cpp(11) : info C5002: loop not vectorized due to reason '1200'</p>
  </blockquote>
  
  <p>This means that the "[l]oop contains loop-carried data dependences".</p>
  
  <p><strong>I have noticed that commenting either the constructor or the destructor for <code>Vec</code> (edit: or defaulting them, e.g. <code>Vec()=default;</code>) causes it to vectorize successfully.  My question: why?</strong></p>
  
  <hr>
  
  <p>Note: Toggling the <code>#if</code> will also make it work.  The <code>__restrict</code> is important.<br/>
  Note: Changing <code>float const&amp; scalar</code> to <code>float const scalar</code> causes the vectorization to report <code>1303</code> (vectorization wouldn't be a win), I suspect because the reference can be passed directly into an SSE register while the pass-by-value needs another copy.</p>