title: Why is gcc allowed to speculatively load from a struct?
body: <h2>Example Showing the gcc Optimization and User Code that May Fault</h2>
  
  <p>The function 'foo' in the snippet below will load only one of the struct members A or B; well at least that is the intention of the unoptimized code.</p>
  
  <pre><code>typedef struct {
    int A;
    int B;
  } Pair;
  
  int foo(const Pair *P, int c) {
    int x;
    if (c)
      x = P-&gt;A;
    else
      x = P-&gt;B;
    return c/102 + x;
  }
  </code></pre>
  
  <p>Here is what gcc -O3 gives:</p>
  
  <pre><code>mov eax, esi
  mov edx, -1600085855
  test esi, esi
  mov ecx, DWORD PTR [rdi+4]   &lt;-- ***load P-&gt;B**
  cmovne ecx, DWORD PTR [rdi]  &lt;-- ***load P-&gt;A***
  imul edx
  lea eax, [rdx+rsi]
  sar esi, 31
  sar eax, 6
  sub eax, esi
  add eax, ecx
  ret
  </code></pre>
  
  <p>So it appears that gcc is allowed to speculatively load both struct members in order to eliminate branching. But then, is the following code considered undefined behavior or is the gcc optimization above illegal?</p>
  
  <pre><code>#include &lt;stdlib.h&gt;  
  
  int naughty_caller(int c) {
    Pair *P = (Pair*)malloc(sizeof(Pair)-1); // *** Allocation is enough for A but not for B ***
    if (!P) return -1;
  
    P-&gt;A = 0x42; // *** Initializing allocation only where it is guaranteed to be allocated ***
  
    int res = foo(P, 1); // *** Passing c=1 to foo should ensure only P-&gt;A is accessed? ***
  
    free(P);
    return res;
  }
  </code></pre>
  
  <p>If the load speculation will happen in the above scenario there is a chance that loading P->B will cause an exception because the last byte of P->B may lie in unallocated memory. This exception will not happen if the optimization is turned off.</p>
  
  <h2>The Question</h2>
  
  <p>Is the gcc optimization shown above of load speculation legal? Where does the spec say or imply that it's ok?
  If the optimization is legal, how is the code in 'naughtly_caller' turn out to be undefined behavior?</p>