<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Union store codegen is silly"
   href="https://llvm.org/bugs/show_bug.cgi?id=31777">31777</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Union store codegen is silly
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Common Code Generator Code
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>llvm-bugzilla@jfbastien.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider this code:

#include <inttypes.h>
#include <string.h>

union U {
  uint64_t i;
  uint16_t s;
};

void foo(U* u) {
  u->i = 0;
  u->s = 42;
}

void bar(U* u) {
  memset(u, 0, sizeof(U));
  u->s = 42;
}

void baz(U* u) {
  u->s = 42;
}


Let's ignore that foo could ignore the zero stores (because i isn't the active
member after the store to s): the codegen for this is pretty suboptimal
(<a href="https://godbolt.org/g/yS10Ki">https://godbolt.org/g/yS10Ki</a>). The user's intent was to zero out padding bits,
and in many architectures you only need one store to do so (with, in some
cases, one materialization of the value).

x86-64:

foo(U*):                              # @foo(U*)
        movq    $0, (%rdi)
        movw    $42, (%rdi)
        retq

bar(U*):                              # @bar(U*)
        movq    $0, (%rdi)
        movw    $42, (%rdi)
        retq

baz(U*):                              # @baz(U*)
        movw    $42, (%rdi)
        retq

ARMv8:

foo(U*):
        mov     r1, #0
        str     r1, [r0]
        str     r1, [r0, #4]
        mov     r1, #42
        strh    r1, [r0]
        bx      lr

bar(U*):
        mov     r1, #0
        str     r1, [r0]
        str     r1, [r0, #4]
        mov     r1, #42
        strh    r1, [r0]
        bx      lr

baz(U*):
        mov     r1, #42
        strh    r1, [r0]
        bx      lr



I'd expect foo and bar to look like what GCC 7 trunk does:

foo(U*):
        movq    $42, (%rdi)
        ret</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>