title: Does compiler only unroll the outer loop completely?
body: <p>I try to compile this code and use loop-specific pragmas to tell the compiler how many times to unroll a counted loop.</p>
  <pre><code>#include &lt;vector&gt;
  int main() {
    std::vector&lt;int&gt; v(8192);
  #pragma GCC unroll 8 // 16
    for (int i = 0; i &lt; 16; i++) {
      for (int j = 0; j &lt; 512; j++) {
        v[i*512+j] = i*j;
      }
    }
    return 0;
  }
  </code></pre>
  <p>When I place the <code>#pragma GCC unroll 8</code> before the outer <code>for</code> loop, the compiler does't unroll.</p>
  <pre><code>.L3:
          movd    xmm7, ecx
          mov     rax, rsi
          movdqa  xmm2, xmm6
          pshufd  xmm3, xmm7, 0
          movdqa  xmm4, xmm3
          psrlq   xmm4, 32
  .L4:
          movdqa  xmm0, xmm2
          movdqa  xmm1, xmm3
          paddd   xmm2, xmm5
          add     rax, 16
          pmuludq xmm1, xmm0
          psrlq   xmm0, 32
          pmuludq xmm0, xmm4
          pshufd  xmm1, xmm1, 8
          pshufd  xmm0, xmm0, 8
          punpckldq       xmm1, xmm0
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L4
          add     ecx, 1
          add     rsi, 2048
          lea     rdx, [rax+2048]
          cmp     ecx, 16
          jne     .L3
          mov     rdi, rbp
          mov     esi, 16384
          call    _ZdlPvm
          xor     eax, eax
          pop     rbp
          ret
  </code></pre>
  <p>But when I place the <code>#pragma GCC unroll 16</code> before the outer <code>for</code> loop, the compiler unroll the outer loop successfully.</p>
  <pre><code>.L2:
          lea     rdi, [rbp+8]
          mov     rcx, rbp
          movdqa  xmm2, XMMWORD PTR .LC0[rip]
          xor     eax, eax
          and     rdi, -8
          movdqa  xmm0, XMMWORD PTR .LC1[rip]
          mov     QWORD PTR [rbp+0], 0
          lea     rdx, [rbp+4096]
          sub     rcx, rdi
          movdqa  xmm1, xmm2
          mov     QWORD PTR [rbp+2040], 0
          add     ecx, 2048
          shr     ecx, 3
          rep stosq
          lea     rax, [rbp+2048]
  .L3:
          movdqa  xmm3, xmm1
          add     rax, 16
          paddd   xmm1, xmm0
          movups  XMMWORD PTR [rax-16], xmm3
          cmp     rax, rdx
          jne     .L3
          lea     rdx, [rbp+6144]
          movdqa  xmm3, xmm2
  .L4:
          movdqa  xmm1, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          pslld   xmm1, 1
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L4
          lea     rdx, [rbp+8192]
          movdqa  xmm3, xmm2
  .L5:
          movdqa  xmm4, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 1
          paddd   xmm1, xmm4
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rdx, rax
          jne     .L5
          mov     rax, rdx
          movdqa  xmm3, xmm2
          lea     rdx, [rbp+10240]
  .L6:
          movdqa  xmm1, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          pslld   xmm1, 2
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L6
          mov     rdx, rax
          movdqa  xmm3, xmm2
          lea     rax, [rbp+12288]
  .L7:
          movdqa  xmm4, xmm3
          add     rdx, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 2
          paddd   xmm1, xmm4
          movups  XMMWORD PTR [rdx-16], xmm1
          cmp     rax, rdx
          jne     .L7
          lea     rdx, [rbp+14336]
          movdqa  xmm3, xmm2
  .L8:
          movdqa  xmm4, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 1
          paddd   xmm1, xmm4
          pslld   xmm1, 1
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L8
          movdqa  xmm3, xmm2
  .L9:
          movdqa  xmm4, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 3
          psubd   xmm1, xmm4
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rbx
          jne     .L9
          lea     rdx, [rbp+18432]
          movdqa  xmm3, xmm2
  .L10:
          movdqa  xmm1, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          pslld   xmm1, 3
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L10
          lea     rdx, [rbp+20480]
          movdqa  xmm3, xmm2
  .L11:
          movdqa  xmm4, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 3
          paddd   xmm1, xmm4
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rdx, rax
          jne     .L11
          lea     rax, [rbp+22528]
          movdqa  xmm3, xmm2
  .L12:
          movdqa  xmm4, xmm3
          add     rdx, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 2
          paddd   xmm1, xmm4
          pslld   xmm1, 1
          movups  XMMWORD PTR [rdx-16], xmm1
          cmp     rax, rdx
          jne     .L12
          lea     rdx, [rbp+24576]
          movdqa  xmm4, xmm2
  .L13:
          movdqa  xmm3, xmm4
          add     rax, 16
          paddd   xmm4, xmm0
          movdqa  xmm1, xmm3
          pslld   xmm1, 1
          paddd   xmm1, xmm3
          pslld   xmm1, 2
          psubd   xmm1, xmm3
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L13
          lea     rdx, [rbp+26624]
          movdqa  xmm3, xmm2
  .L14:
          movdqa  xmm4, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 1
          paddd   xmm1, xmm4
          pslld   xmm1, 2
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L14
          lea     rdx, [rbp+28672]
          movdqa  xmm4, xmm2
  .L15:
          movdqa  xmm3, xmm4
          add     rax, 16
          paddd   xmm4, xmm0
          movdqa  xmm1, xmm3
          pslld   xmm1, 1
          paddd   xmm1, xmm3
          pslld   xmm1, 2
          paddd   xmm1, xmm3
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rax, rdx
          jne     .L15
          lea     rdx, [rbp+30720]
          movdqa  xmm3, xmm2
  .L16:
          movdqa  xmm4, xmm3
          add     rax, 16
          paddd   xmm3, xmm0
          movdqa  xmm1, xmm4
          pslld   xmm1, 3
          psubd   xmm1, xmm4
          pslld   xmm1, 1
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rdx, rax
          jne     .L16
          mov     rax, rdx
          lea     rdx, [rbp+32768]
  .L17:
          movdqa  xmm3, xmm2
          add     rax, 16
          paddd   xmm2, xmm0
          movdqa  xmm1, xmm3
          pslld   xmm1, 4
          psubd   xmm1, xmm3
          movups  XMMWORD PTR [rax-16], xmm1
          cmp     rdx, rax
          jne     .L17
          mov     rdi, rbp
          mov     esi, 16384
          call    _ZdlPvm
          add     rsp, 8
          xor     eax, eax
          pop     rbx
          pop     rbp
          ret
  </code></pre>
  <p>So does compiler only unroll the outer loop completely?</p>
  <p>GCC version: g++ (Compiler-Explorer-Build-gcc-b8ef019ab938471f7f877a1eee3a6374fd8a6ae9-binutils-2.36.1) 12.0.0 20211029 (experimental)</p>
  <p>Option: -O2</p>
  <p>godbolt: <a href="https://godbolt.org/z/zq7TWesY9" rel="nofollow noreferrer">https://godbolt.org/z/zq7TWesY9</a></p>