mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
LegalizeTypes support for legalizing the mask
operand of a VECTOR_SHUFFLE. The mask is a vector of constant integers. The code in LegalizeDAG doesn't bother to legalize the mask, since it's basically just storage for a bunch of constants, however LegalizeTypes is more picky. The problem is that there may not exist any legal vector-of-integers type with a legal element type, so it is impossible to create a legal mask! Unless of course you cheat by creating a BUILD_VECTOR where the operands have a different type to the element type of the vector being built... This is pretty ugly but works - all relevant tests in the testsuite pass, and produce the same assembler with and without LegalizeTypes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47670 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4f069e6db1
commit
8745b52853
@ -316,6 +316,7 @@ private:
|
||||
SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N);
|
||||
SDOperand SplitOp_RET(SDNode *N, unsigned OpNo);
|
||||
SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo);
|
||||
SDOperand SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo);
|
||||
};
|
||||
|
||||
} // end namespace llvm.
|
||||
|
@ -341,6 +341,7 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::RET: Res = SplitOp_RET(N, OpNo); break;
|
||||
|
||||
case ISD::EXTRACT_SUBVECTOR: Res = SplitOp_EXTRACT_SUBVECTOR(N); break;
|
||||
case ISD::VECTOR_SHUFFLE: Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,3 +422,57 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
|
||||
DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
|
||||
}
|
||||
}
|
||||
|
||||
SDOperand DAGTypeLegalizer::SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
|
||||
assert(OpNo == 2 && "Shuffle source type differs from result type?");
|
||||
SDOperand Mask = N->getOperand(2);
|
||||
unsigned MaskLength = MVT::getVectorNumElements(Mask.getValueType());
|
||||
unsigned LargestMaskEntryPlusOne = 2 * MaskLength;
|
||||
unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne);
|
||||
|
||||
// Look for a legal vector type to place the mask values in.
|
||||
// Note that there may not be *any* legal vector-of-integer
|
||||
// type for which the element type is legal!
|
||||
for (MVT::SimpleValueType EltVT = MVT::FIRST_INTEGER_VALUETYPE;
|
||||
EltVT <= MVT::LAST_INTEGER_VALUETYPE;
|
||||
// Integer values types are consecutively numbered. Exploit this.
|
||||
EltVT = MVT::SimpleValueType(EltVT + 1)) {
|
||||
|
||||
// Is the element type big enough to hold the values?
|
||||
if (MVT::getSizeInBits(EltVT) < MinimumBitWidth)
|
||||
// Nope.
|
||||
continue;
|
||||
|
||||
// Is the vector type legal?
|
||||
MVT::ValueType VecVT = MVT::getVectorType(EltVT, MaskLength);
|
||||
if (!isTypeLegal(VecVT))
|
||||
// Nope.
|
||||
continue;
|
||||
|
||||
// If the element type is not legal, find a larger legal type to use for
|
||||
// the BUILD_VECTOR operands. This is an ugly hack, but seems to work!
|
||||
for (MVT::SimpleValueType OpVT = EltVT; OpVT <= MVT::LAST_INTEGER_VALUETYPE;
|
||||
// Integer values types are consecutively numbered. Exploit this.
|
||||
OpVT = MVT::SimpleValueType(OpVT + 1)) {
|
||||
if (!isTypeLegal(OpVT))
|
||||
continue;
|
||||
|
||||
// Success! Rebuild the vector using the legal types.
|
||||
SmallVector<SDOperand, 16> Ops(MaskLength);
|
||||
for (unsigned i = 0; i < MaskLength; ++i) {
|
||||
uint64_t Idx =
|
||||
cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
|
||||
Ops[i] = DAG.getConstant(Idx, OpVT);
|
||||
}
|
||||
return DAG.UpdateNodeOperands(SDOperand(N,0),
|
||||
N->getOperand(0), N->getOperand(1),
|
||||
DAG.getNode(ISD::BUILD_VECTOR,
|
||||
VecVT, &Ops[0], Ops.size()));
|
||||
}
|
||||
|
||||
// Continuing is pointless - failure is certain.
|
||||
break;
|
||||
}
|
||||
assert(false && "Failed to find an appropriate mask type!");
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user