forked from OSchip/llvm-project
[SystemZ] Gracefully fail in GeneralShuffle::add() instead of assertion.
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. llvm-svn: 292888
This commit is contained in:
parent
d7e0e6b514
commit
463e2a6f3d
|
@ -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.
|
||||
|
@ -3828,8 +3828,10 @@ 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,
|
||||
|
@ -3837,8 +3839,12 @@ void GeneralShuffle::add(SDValue Op, unsigned Elem) {
|
|||
// 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));
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue