title: SIGSEGV in optimized version of code
body: <p>My knowledge of the intel instruction set is a bit rusty.  Can you tell me why I might be getting a segmentation fault in the optimized version of my function (bonus points if you can tell me why I don't get it in the -O0 build of the code.</p>
  
  <p>It's C code compiled by GCC 4.1.2.</p>
  
  <p>Here is the result of GDB's "disas" command at the crash:</p>
  
  <pre><code>   0x00000000004263e5 &lt;+0&gt;:     sub    $0x8,%rsp
     0x00000000004263e9 &lt;+4&gt;:     movsd  %xmm2,(%rsp)
     0x00000000004263ee &lt;+9&gt;:     divsd  %xmm1,%xmm0
     0x00000000004263f2 &lt;+13&gt;:    callq  0x60f098 &lt;log@plt&gt;
  =&gt; 0x00000000004263f7 &lt;+18&gt;:    andpd  0x169529(%rip),%xmm0        
     0x00000000004263ff &lt;+26&gt;:    movsd  (%rsp),%xmm1
     0x0000000000426404 &lt;+31&gt;:    ucomisd %xmm0,%xmm1
     0x0000000000426408 &lt;+35&gt;:    seta   %al
     0x000000000042640b &lt;+38&gt;:    movzbl %al,%eax
     0x000000000042640e &lt;+41&gt;:    add    $0x8,%rsp
     0x0000000000426412 &lt;+45&gt;:    retq   
  </code></pre>
  
  <p>And here's the original source of the function:</p>
  
  <pre><code>char is_within_range(double a, double b, double range) {
    double ratio = a / b;
    double logRatio = fabs(log(ratio));
    return logRatio &lt; range;
  }
  </code></pre>
  
  <p>For reference here's the non-optimized version of the code:</p>
  
  <pre><code>   0x00000000004263e5 &lt;+0&gt;: push   %rbp
     0x00000000004263e6 &lt;+1&gt;: mov    %rsp,%rbp
     0x00000000004263e9 &lt;+4&gt;: sub    $0x30,%rsp
     0x00000000004263ed &lt;+8&gt;: movsd  %xmm0,-0x18(%rbp)
     0x00000000004263f2 &lt;+13&gt;:    movsd  %xmm1,-0x20(%rbp)
     0x00000000004263f7 &lt;+18&gt;:    movsd  %xmm2,-0x28(%rbp)
     0x00000000004263fc &lt;+23&gt;:    movsd  -0x18(%rbp),%xmm0
     0x0000000000426401 &lt;+28&gt;:    divsd  -0x20(%rbp),%xmm0
     0x0000000000426406 &lt;+33&gt;:    movsd  %xmm0,-0x10(%rbp)
     0x000000000042640b &lt;+38&gt;:    mov    -0x10(%rbp),%rax
     0x000000000042640f &lt;+42&gt;:    mov    %rax,-0x30(%rbp)
     0x0000000000426413 &lt;+46&gt;:    movsd  -0x30(%rbp),%xmm0
     0x0000000000426418 &lt;+51&gt;:    callq  0x610608 &lt;log@plt&gt;
     0x000000000042641d &lt;+56&gt;:    movapd %xmm0,%xmm1
     0x0000000000426421 &lt;+60&gt;:    movsd  0x16b6b7(%rip),%xmm0
     0x0000000000426429 &lt;+68&gt;:    andpd  %xmm1,%xmm0
     0x000000000042642d &lt;+72&gt;:    movsd  %xmm0,-0x8(%rbp)
     0x0000000000426432 &lt;+77&gt;:    movsd  -0x8(%rbp),%xmm1
     0x0000000000426437 &lt;+82&gt;:    movsd  -0x28(%rbp),%xmm0
     0x000000000042643c &lt;+87&gt;:    ucomisd %xmm1,%xmm0
     0x0000000000426440 &lt;+91&gt;:    seta   %al
     0x0000000000426443 &lt;+94&gt;:    movzbl %al,%eax
     0x0000000000426446 &lt;+97&gt;:    leaveq 
     0x0000000000426447 &lt;+98&gt;:    retq   
  </code></pre>