[PATCH] D12591: Fix vector splitting for extract_vector_elt and vector elements of <8-bits.

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 3 02:07:19 PDT 2015


dsanders created this revision.
dsanders added subscribers: llvm-commits, pekka.jaaskelainen.

One of the vector splitting paths for extract_vector_elt tries to lower:
    define i1 @via_stack_bug(i8 signext %idx) {
      %1 = extractelement <2 x i1> <i1 false, i1 true>, i8 %idx
      ret i1 %1
    }
to:
    define i1 @via_stack_bug(i8 signext %idx) {
      %base = alloca <2 x i1>
      store <2 x i1> <i1 false, i1 true>, <2 x i1>* %base
      %2 = getelementptr <2 x i1>, <2 x i1>* %base, i32 %idx
      %3 = load i1, i1* %2
      ret i1 %3
    }
However, the elements of <2 x i1> are not byte-addressible. The result of this
is that the getelementptr expands to '%base + %idx * (1 / 8)' which simplifies
to '%base + %idx * 0', and then simply '%base' causing all values of %idx to
extract element zero.

This commit fixes this by promoting the vector elements of <8-bits to i8 before
splitting the vector.

This fixes a number of test failures in pocl.

http://reviews.llvm.org/D12591

Files:
  lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
  lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
  test/CodeGen/Mips/llvm-ir/extractelement.ll

Index: test/CodeGen/Mips/llvm-ir/extractelement.ll
===================================================================
--- /dev/null
+++ test/CodeGen/Mips/llvm-ir/extractelement.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s -check-prefix=ALL
+
+; This test triggered a bug in the vector splitting where the type legalizer
+; attempted to extract the element with by storing the vector, then reading
+; an element back. However, the address calculation was:
+;   Base + Index * (EltSizeInBits / 8)
+; and EltSizeInBits was 1. This caused the index to be forgotten.
+define i1 @via_stack_bug(i8 signext %idx) {
+  %1 = extractelement <2 x i1> <i1 false, i1 true>, i8 %idx
+  ret i1 %1
+}
+
+; ALL-LABEL: via_stack_bug:
+; ALL-DAG:       addiu  [[ONE:\$[0-9]+]], $zero, 1
+; ALL-DAG:       sb     [[ONE]], 7($sp)
+; ALL-DAG:       sb     $zero, 6($sp)
+; ALL-DAG:       addiu  [[VPTR:\$[0-9]+]], $sp, 6
+; ALL-DAG:       addu   [[EPTR:\$[0-9]+]], $4, [[VPTR]]
+; ALL:           lbu    $2, 0([[EPTR]])
Index: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1554,9 +1554,25 @@
   if (CustomLowerNode(N, N->getValueType(0), true))
     return SDValue();
 
-  // Store the vector to the stack.
-  EVT EltVT = VecVT.getVectorElementType();
+  // Make the vector elements byte-addressable if they aren't already.
   SDLoc dl(N);
+  EVT EltVT = VecVT.getVectorElementType();
+  if (EltVT.getSizeInBits() < 8) {
+    SmallVector<SDValue, 4> ElementOps;
+    for (unsigned i = 0; i < VecVT.getVectorNumElements(); ++i) {
+      ElementOps.push_back(DAG.getAnyExtOrTrunc(
+          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Vec,
+                      DAG.getConstant(i, dl, MVT::i8)),
+          dl, MVT::i8));
+    }
+
+    EltVT = MVT::i8;
+    VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
+                             VecVT.getVectorNumElements());
+    Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, VecVT, ElementOps);
+  }
+
+  // Store the vector to the stack.
   SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr,
                                MachinePointerInfo(), false, false, 0);
Index: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -1007,6 +1007,8 @@
 
   // Calculate the element offset and add it to the pointer.
   unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size.
+  assert(EltSize * 8 == EltVT.getSizeInBits() &&
+         "Converting bits to bytes lost precision");
 
   Index = DAG.getNode(ISD::MUL, dl, Index.getValueType(), Index,
                       DAG.getConstant(EltSize, dl, Index.getValueType()));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12591.33914.patch
Type: text/x-patch
Size: 2996 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150903/1092dbda/attachment.bin>


More information about the llvm-commits mailing list