[LLVMbugs] [Bug 22603] New: SelectionDag incorrectly legalizes vNi1 load/stores, leading to miscomputes.

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Feb 16 10:27:50 PST 2015


            Bug ID: 22603
           Summary: SelectionDag incorrectly legalizes vNi1 load/stores,
                    leading to miscomputes.
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: lhames at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

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() {
  %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:

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

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

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150216/9b468011/attachment.html>

More information about the llvm-bugs mailing list