title: Understanding GCC's alloca() alignment and seemingly missed optimization
body: <p>Consider the following toy example that allocates memory on the stack by means of the <code>alloca()</code> function:</p>
  
  <pre><code>#include &lt;alloca.h&gt;
  
  void foo() {
      volatile int *p = alloca(4);
      *p = 7;
  }
  </code></pre>
  
  <p>Compiling the function above using gcc 8.2 with <code>-O3</code> results in the following assembly code:</p>
  
  <pre><code>foo:
     pushq   %rbp
     movq    %rsp, %rbp
     subq    $16, %rsp
     leaq    15(%rsp), %rax
     andq    $-16, %rax
     movl    $7, (%rax)
     leave
     ret
  </code></pre>
  
  <p>Honestly, I would have expected a more compact assembly code.</p>
  
  <hr>
  
  <h3>16-byte alignment for allocated memory</h3>
  
  <p>The instruction <code>andq $-16, %rax</code> in the code above results in <code>rax</code> containing the (only) <em>16-byte-aligned</em> address between the addresses <code>rsp</code> and <code>rsp + 15</code> (both inclusive).</p>
  
  <p>This alignment enforcement is the first thing I don't understand: Why does <code>alloca()</code> align the allocated memory to a 16-byte boundary?</p>
  
  <hr>
  
  <h3>Possible missed optimization?</h3>
  
  <p>Let's consider anyway that we want the memory allocated by <code>alloca()</code> to be 16-byte aligned. Even so, in the assembly code above, keeping in mind that GCC assumes the stack to be aligned to a 16-byte boundary at the moment of performing the function call (i.e., <code>call foo</code>), if we pay attention to the status of the stack inside <code>foo()</code> <em>just after</em> pushing the <code>rbp</code> register:</p>
  
  <pre><code>Size          Stack          RSP mod 16      Description
  -----------------------------------------------------------------------------------
          ------------------
          |       .        |
          |       .        | 
          |       .        |            
          ------------------........0          at "call foo" (stack 16-byte aligned)
  8 bytes | return address |
          ------------------........8          at foo entry
  8 bytes |   saved RBP    |
          ------------------........0  &lt;-----  RSP is 16-byte aligned!!!
  </code></pre>
  
  <p>I think that by taking advantage of the <em><a href="https://en.wikipedia.org/wiki/Red_zone_(computing)" rel="nofollow noreferrer">red zone</a></em> (i.e., no need to modify <code>rsp</code>) and the fact that <code>rsp</code> already contains a <em>16-byte aligned address</em>, the following code could be used instead:</p>
  
  <pre><code>foo:
     pushq   %rbp
     movq    %rsp, %rbp
     movl    $7, -16(%rbp)
     leave
     ret
  </code></pre>
  
  <p>The address contained in the register <code>rbp</code> is 16-byte aligned, therefore <code>rbp - 16</code> will also be aligned to a 16-byte boundary.</p>
  
  <p>Even better, the creation of the new stack frame can be optimized away, since <code>rsp</code> is not modified:</p>
  
  <pre><code>foo:
     movl    $7, -8(%rsp)
     ret
  </code></pre>
  
  <p>Is this just a missed optimization or I am missing something else here?</p>