mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
SDAG: Legalize vector BSWAP into a shuffle if the shuffle is legal but the bswap not.
- On ARM/ARM64 we get a vrev because the shuffle matching code is really smart. We still unroll anything that's not v4i32 though. - On X86 we get a pshufb with SSSE3. Required more cleverness in isShuffleMaskLegal. - On PPC we get a vperm for v8i16 and v4i32. v2i64 is unrolled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209123 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -63,6 +63,8 @@ class VectorLegalizer {
|
||||
SDValue ExpandUINT_TO_FLOAT(SDValue Op);
|
||||
// Implement expansion for SIGN_EXTEND_INREG using SRL and SRA.
|
||||
SDValue ExpandSEXTINREG(SDValue Op);
|
||||
// Expand bswap of vectors into a shuffle if legal.
|
||||
SDValue ExpandBSWAP(SDValue Op);
|
||||
// Implement vselect in terms of XOR, AND, OR when blend is not supported
|
||||
// by the target.
|
||||
SDValue ExpandVSELECT(SDValue Op);
|
||||
@@ -297,6 +299,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
|
||||
case TargetLowering::Expand:
|
||||
if (Node->getOpcode() == ISD::SIGN_EXTEND_INREG)
|
||||
Result = ExpandSEXTINREG(Op);
|
||||
else if (Node->getOpcode() == ISD::BSWAP)
|
||||
Result = ExpandBSWAP(Op);
|
||||
else if (Node->getOpcode() == ISD::VSELECT)
|
||||
Result = ExpandVSELECT(Op);
|
||||
else if (Node->getOpcode() == ISD::SELECT)
|
||||
@@ -682,6 +686,29 @@ SDValue VectorLegalizer::ExpandSEXTINREG(SDValue Op) {
|
||||
return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
|
||||
}
|
||||
|
||||
SDValue VectorLegalizer::ExpandBSWAP(SDValue Op) {
|
||||
EVT VT = Op.getValueType();
|
||||
|
||||
// Generate a byte wise shuffle mask for the BSWAP.
|
||||
SmallVector<int, 16> ShuffleMask;
|
||||
int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
|
||||
for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
|
||||
for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
|
||||
ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
|
||||
|
||||
EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
|
||||
|
||||
// Only emit a shuffle if the mask is legal.
|
||||
if (!TLI.isShuffleMaskLegal(ShuffleMask, ByteVT))
|
||||
return DAG.UnrollVectorOp(Op.getNode());
|
||||
|
||||
SDLoc DL(Op);
|
||||
Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Op.getOperand(0));
|
||||
Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT),
|
||||
ShuffleMask.data());
|
||||
return DAG.getNode(ISD::BITCAST, DL, VT, Op);
|
||||
}
|
||||
|
||||
SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
|
||||
// Implement VSELECT in terms of XOR, AND, OR
|
||||
// on platforms which do not support blend natively.
|
||||
|
Reference in New Issue
Block a user