<html>
    <head>
      <base href="http://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 --- - SelectionDag incorrectly legalizes vNi1 load/stores, leading to miscomputes."
   href="http://llvm.org/bugs/show_bug.cgi?id=22603">22603</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SelectionDag incorrectly legalizes vNi1 load/stores, leading to miscomputes.
          </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>lhames@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>SelectionDAG's logic for legalizing vNi1 vector load/stores is broken, leading
to miscompiles.

E.g: Consider the following bitcode, which stores and then reloads a v4i1, then
extracts one of the bits. (The extra dummy alloca and store are there to block
any trivial optimizations from removing the memory operations.)

define i32 @bad_store() {
bb:
  %dummy = alloca i32          ; Additional stack slot to block optimizers.
  %vec_slot = alloca <4 x i1>
  store <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i1>* %vec_slot
  store i32 0, i32* %dummy     ; Store to dummy stack slot.
  %vec_val = load <4 x i1>* %vec_slot
  %bit_val = extractelement <4 x i1> %vec_val, i32 1
  %ret_val = zext i1 %bit_val to i32
  ret i32 %ret_val
}

This compiles to:

bad_store:
        subl    $8, %esp
    movb    $0, (%esp)
    movb    $1, (%esp)
    movl    $0, 4(%esp)
    movzbl    (%esp), %eax
    addl    $8, %esp
    ret

There are two byte stores to %vec_slot, with the second wiping out the value of
the first. The reload then fails to do any shifting/masking to extract bit 1
for the return. The result is that this function will return 'true', whereas
element 1 of the vector constant was 'false'.

The problem seems to be the logic in DAGTypeLegalizer::SplitVecOp_STORE and
VectorLegalizer::ExpandStore. Both are assuming that the vector elements are
bigger than a char, and that the vector memory operation can be broken up into
smaller legalizable memory operations. That's clearly not the case on x86 with
anything smaller than an i8.

Fixing this would require deciding on a default layout for vNi1s in memory,
which is non obvious. I made some headway getting this test case to compile
correctly by having the legalizer bitcast such vectors to integers before
loading and storing, but it's not obvious to me that that's appropriate in
general.</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>