Skip to content

Commit

Permalink
[SystemZ] Gracefully fail in GeneralShuffle::add() instead of assertion.
Browse files Browse the repository at this point in the history
The GeneralShuffle::add() method used to have an assert that made sure that
source elements were at least as big as the destination elements. This was
wrong, since it is actually expected that an EXTRACT_VECTOR_ELT node with a
smaller source element type than the return type gets extended.

Therefore, instead of asserting this, it is just checked and if this is the
case 'false' is returned from the GeneralShuffle::add() method. This case
should be very rare and is not handled further by the backend.

Review: Ulrich Weigand.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292888 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
JonPsson committed Jan 24, 2017
1 parent 0f21af6 commit d16497e
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions lib/Target/SystemZ/SystemZISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3802,7 +3802,7 @@ namespace {
struct GeneralShuffle {
GeneralShuffle(EVT vt) : VT(vt) {}
void addUndef();
void add(SDValue, unsigned);
bool add(SDValue, unsigned);
SDValue getNode(SelectionDAG &, const SDLoc &);

// The operands of the shuffle.
Expand All @@ -3828,17 +3828,23 @@ void GeneralShuffle::addUndef() {
// Add an extra element to the shuffle, taking it from element Elem of Op.
// A null Op indicates a vector input whose value will be calculated later;
// there is at most one such input per shuffle and it always has the same
// type as the result.
void GeneralShuffle::add(SDValue Op, unsigned Elem) {
// type as the result. Aborts and returns false if the source vector elements
// of an EXTRACT_VECTOR_ELT are smaller than the destination elements. Per
// LLVM they become implicitly extended, but this is rare and not optimized.
bool GeneralShuffle::add(SDValue Op, unsigned Elem) {
unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();

// The source vector can have wider elements than the result,
// either through an explicit TRUNCATE or because of type legalization.
// We want the least significant part.
EVT FromVT = Op.getNode() ? Op.getValueType() : VT;
unsigned FromBytesPerElement = FromVT.getVectorElementType().getStoreSize();
assert(FromBytesPerElement >= BytesPerElement &&
"Invalid EXTRACT_VECTOR_ELT");

// Return false if the source elements are smaller than their destination
// elements.
if (FromBytesPerElement < BytesPerElement)
return false;

unsigned Byte = ((Elem * FromBytesPerElement) % SystemZ::VectorBytes +
(FromBytesPerElement - BytesPerElement));

Expand All @@ -3856,13 +3862,13 @@ void GeneralShuffle::add(SDValue Op, unsigned Elem) {
break;
if (NewByte < 0) {
addUndef();
return;
return true;
}
Op = Op.getOperand(unsigned(NewByte) / SystemZ::VectorBytes);
Byte = unsigned(NewByte) % SystemZ::VectorBytes;
} else if (Op.isUndef()) {
addUndef();
return;
return true;
} else
break;
}
Expand All @@ -3879,6 +3885,8 @@ void GeneralShuffle::add(SDValue Op, unsigned Elem) {
unsigned Base = OpNo * SystemZ::VectorBytes + Byte;
for (unsigned I = 0; I < BytesPerElement; ++I)
Bytes.push_back(Base + I);

return true;
}

// Return SDNodes for the completed shuffle.
Expand Down Expand Up @@ -4110,12 +4118,14 @@ static SDValue tryBuildVectorShuffle(SelectionDAG &DAG,
if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
Op.getOperand(1).getOpcode() == ISD::Constant) {
unsigned Elem = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
GS.add(Op.getOperand(0), Elem);
if (!GS.add(Op.getOperand(0), Elem))
return SDValue();
FoundOne = true;
} else if (Op.isUndef()) {
GS.addUndef();
} else {
GS.add(SDValue(), ResidueOps.size());
if (!GS.add(SDValue(), ResidueOps.size()))
return SDValue();
ResidueOps.push_back(BVN->getOperand(I));
}
}
Expand Down Expand Up @@ -4354,9 +4364,9 @@ SDValue SystemZTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
int Elt = VSN->getMaskElt(I);
if (Elt < 0)
GS.addUndef();
else
GS.add(Op.getOperand(unsigned(Elt) / NumElements),
unsigned(Elt) % NumElements);
else if (!GS.add(Op.getOperand(unsigned(Elt) / NumElements),
unsigned(Elt) % NumElements))
return SDValue();
}
return GS.getNode(DAG, SDLoc(VSN));
}
Expand Down

0 comments on commit d16497e

Please sign in to comment.