title: Why this behavior on clang -O3?
body: <p>Here is a short program to count the number of divisors of an integer. The program does work correctly. The problem is, however, that under the <code>-O3</code> optimization flag of the current trunk of the Clang C++ compiler (version 3.3, trunk 180686) the behavior of the program changes and the result is no longer correct.</p>
  
  <h3>Code</h3>
  
  <p>Here's the code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  constexpr unsigned long divisors(unsigned long n, unsigned long c)
  {
      // This is supposed to sum 1 anytime a divisor shows up
      // in the recursion
      return !c ? 0 : !(n % c) + divisors(n, c - 1);
  }
  
  int main()
  {
      // Here I print the number of divisors of 9 numbers! (from 1 to 9)
      for (unsigned long i = 1; i &lt; 10; ++i)
          std::cout &lt;&lt; i &lt;&lt; " has " &lt;&lt; divisors(i, i) &lt;&lt; " divisors" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <h3>Correct Behavior</h3>
  
  <p>Here's the compile command used, and the <strong>correct</strong> and expected output, which the program exhibits under normal circumstances:</p>
  
  <pre><code>clang++ -O2 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample
  ./sample 
  1 has 1 divisors
  2 has 2 divisors
  3 has 2 divisors
  4 has 3 divisors
  5 has 2 divisors
  6 has 4 divisors
  7 has 2 divisors
  8 has 4 divisors
  9 has 3 divisors
  </code></pre>
  
  <h3>Incorrect Behavior</h3>
  
  <p>This is the command line used that produces the binary that gives <strong>incorrect</strong> output. Notice that the only change is the optimization flag (<code>-O2</code> to <code>-O3</code>.)</p>
  
  <pre><code>clang++ -O3 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample
  ./sample 
  1 has 1 divisors
  2 has 2 divisors
  3 has 2 divisors
  4 has 1 divisors
  5 has 2 divisors
  6 has 3 divisors
  7 has 2 divisors
  8 has 2 divisors
  9 has 2 divisors
  </code></pre>
  
  <h2>EDIT</h2>
  
  <p>I've updated to tip of trunk, clang version 3.4 (trunk 183073). The behavior does not reproduce anymore, it should have been fixed somehow already. Anyone who knows what issue was it, if there was one actually verified and fixed, please feel free to provide an answer. If there was none verified, a regression may happen.</p>