title: Why does -O3 cause this?
body: <p>I found <a href="http://gcc.godbolt.org/" rel="nofollow">this nice tool</a> that lets you compare code generated by different compilers. Now, take a look at this piece of code:</p>
  
  <pre><code>001    int testFunction(int* input, int length) {
  002      int sum = 0;
  003      for (int i = 0; i &lt; length; ++i) {
  004        sum += input[i];
  005      }
  006      return sum;
  007    }
  </code></pre>
  
  <p>These 24 lines are the output from gcc with no optimization flags:</p>
  
  <pre><code>001    testFunction(int*, int):
  002        pushq    %rbp
  003        movq    %rsp, %rbp
  004        movq    %rdi, -24(%rbp)
  005        movl    %esi, -28(%rbp)
  006        movl    $0, -8(%rbp)
  007        movl    $0, -4(%rbp)
  008        jmp    .L2
  009    .L3:
  010        movl    -4(%rbp), %eax
  011        cltq
  012        leaq    0(,%rax,4), %rdx
  013        movq    -24(%rbp), %rax
  014        addq    %rdx, %rax
  015        movl    (%rax), %eax
  016        addl    %eax, -8(%rbp)
  017        addl    $1, -4(%rbp)
  018    .L2:
  019        movl    -4(%rbp), %eax
  020        cmpl    -28(%rbp), %eax
  021        jl    .L3
  022        movl    -8(%rbp), %eax
  023        popq    %rbp
  024        ret
  </code></pre>
  
  <p>These nice 14 lines are the output from gcc with <code>-O2</code> flag:</p>
  
  <pre><code>001    testFunction(int*, int):
  002        testl    %esi, %esi
  003        jle    .L4
  004        xorl    %edx, %edx
  005        xorl    %eax, %eax
  006    .L3:
  007        addl    (%rdi,%rdx,4), %eax
  008        addq    $1, %rdx
  009        cmpl    %edx, %esi
  010        jg    .L3
  011        rep; ret
  012    .L4:
  013        xorl    %eax, %eax
  014        ret
  </code></pre>
  
  <p>And these 122 lines are the output with <code>-O3</code> flag:</p>
  
  <pre><code>001    testFunction(int*, int):
  002        testl    %esi, %esi
  003        jle    .L14
  004        movq    %rdi, %rax
  005        movl    %esi, %edx
  006        andl    $15, %eax
  007        shrq    $2, %rax
  008        negq    %rax
  009        andl    $3, %eax
  010        cmpl    %esi, %eax
  011        cmova    %esi, %eax
  012        cmpl    $8, %esi
  013        ja    .L29
  014    .L3:
  015        cmpl    $1, %edx
  016        movl    (%rdi), %eax
  017        jbe    .L17
  018        addl    4(%rdi), %eax
  019        cmpl    $2, %edx
  020        jbe    .L18
  021        addl    8(%rdi), %eax
  022        cmpl    $3, %edx
  023        jbe    .L19
  024        addl    12(%rdi), %eax
  025        cmpl    $4, %edx
  026        jbe    .L20
  027        addl    16(%rdi), %eax
  028        cmpl    $5, %edx
  029        jbe    .L21
  030        addl    20(%rdi), %eax
  031        cmpl    $6, %edx
  032        jbe    .L22
  033        addl    24(%rdi), %eax
  034        cmpl    $7, %edx
  035        jbe    .L23
  036        addl    28(%rdi), %eax
  037        movl    $8, %ecx
  038    .L5:
  039        cmpl    %edx, %esi
  040        je    .L30
  041    .L4:
  042        movl    %esi, %r11d
  043        movl    %edx, %r8d
  044        subl    %edx, %r11d
  045        movl    %r11d, %r9d
  046        shrl    $2, %r9d
  047        leal    0(,%r9,4), %r10d
  048        testl    %r10d, %r10d
  049        je    .L7
  050        pxor    %xmm0, %xmm0
  051        leaq    (%rdi,%r8,4), %r8
  052        xorl    %edx, %edx
  053    .L13:
  054        addl    $1, %edx
  055        paddd    (%r8), %xmm0
  056        addq    $16, %r8
  057        cmpl    %edx, %r9d
  058        ja    .L13
  059        movdqa    %xmm0, %xmm2
  060        addl    %r10d, %ecx
  061        psrldq    $8, %xmm2
  062        paddd    %xmm2, %xmm0
  063        movdqa    %xmm0, %xmm3
  064        psrldq    $4, %xmm3
  065        paddd    %xmm3, %xmm0
  066        movd    %xmm0, -12(%rsp)
  067        addl    -12(%rsp), %eax
  068        cmpl    %r10d, %r11d
  069        je    .L2
  070    .L7:
  071        movslq    %ecx, %rdx
  072        addl    (%rdi,%rdx,4), %eax
  073        leal    1(%rcx), %edx
  074        cmpl    %edx, %esi
  075        jle    .L2
  076        movslq    %edx, %rdx
  077        addl    $2, %ecx
  078        addl    (%rdi,%rdx,4), %eax
  079        cmpl    %ecx, %esi
  080        jle    .L31
  081        movslq    %ecx, %rcx
  082        addl    (%rdi,%rcx,4), %eax
  083        ret
  084    .L14:
  085        xorl    %eax, %eax
  086    .L2:
  087        rep; ret
  088    .L30:
  089        rep; ret
  090    .L29:
  091        testl    %eax, %eax
  092        jne    .L32
  093        xorl    %edx, %edx
  094        xorl    %ecx, %ecx
  095        xorl    %eax, %eax
  096        jmp    .L4
  097    .L31:
  098        rep; ret
  099    .L18:
  100        movl    $2, %ecx
  101        jmp    .L5
  102    .L23:
  103        movl    $7, %ecx
  104        jmp    .L5
  105    .L17:
  106        movl    $1, %ecx
  107        jmp    .L5
  108    .L19:
  109        movl    $3, %ecx
  110        jmp    .L5
  111    .L20:
  112        movl    $4, %ecx
  113        jmp    .L5
  114    .L21:
  115        movl    $5, %ecx
  116        jmp    .L5
  117    .L22:
  118        movl    $6, %ecx
  119        jmp    .L5
  120    .L32:
  121        movl    %eax, %edx
  122        jmp    .L3
  </code></pre>
  
  <p>Clang behaves similarly too.</p>
  
  <p>Am I missing something? I thought -O3 was a higher level of optimization? Is that optimized?</p>