summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2015-09-09 09:53:20 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2015-09-09 09:53:20 +0000
commit2038747fce35d3cab2bd7bfdf8f90cc48051ab2e (patch)
tree2e8252b486dfce1dc835c17953aa5db766f4f3bd /llvm/lib/CodeGen
parent1688a772fcd8929751eedb2b9aa33c41fca46bee (diff)
downloadbcm5719-llvm-2038747fce35d3cab2bd7bfdf8f90cc48051ab2e.tar.gz
bcm5719-llvm-2038747fce35d3cab2bd7bfdf8f90cc48051ab2e.zip
Fix vector splitting for extract_vector_elt and vector elements of <8-bits.
Summary: 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. Reviewers: pekka.jaaskelainen Subscribers: pekka.jaaskelainen, llvm-commits Differential Revision: http://reviews.llvm.org/D12591 llvm-svn: 247128
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp20
2 files changed, 20 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index a97842a9402..7887cf81195 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -1007,6 +1007,8 @@ SDValue DAGTypeLegalizer::GetVectorElementPointer(SDValue VecPtr, EVT EltVT,
// 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()));
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 8551058591c..362a73a484c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1554,9 +1554,25 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
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);
OpenPOWER on IntegriCloud