static bool isByteSwap64(ShuffleVectorInst &SI, SmallVector<int, 16>&RefMasks) { RefMasks.clear(); unsigned VWidth = cast<VectorType>(SI.getType())->getNumElements(); VectorType *LHS = cast<VectorType>(SI.getOperand(0)->getType()); VectorType *RHS = cast<VectorType>(SI.getOperand(1)->getType()); IntegerType *IT = dyn_cast<IntegerType>(LHS->getElementType()); //When Element Type is not IntegerType or the Result's element number //can't be divided by 8, return false //TODO:Need to check all masks are all constants. if (IT == nullptr || ! IT->isIntegerTy(8) || VWidth % 8 != 0) { return false; } SmallVector<int, 16> Masks(SI.getShuffleMask()); bool isByteSwap = true; for (unsigned i = 0; i < VWidth / 8; ++i) { unsigned base = Masks[i * 8]; if (base % 8 != 7) { isByteSwap = false; break; } for (unsigned j = 1; j < 8; ++j) { if (base - Masks[i * 8 + j] != j) { isByteSwap = false; break; } } if (isByteSwap) { RefMasks.push_back(base / 8); } else { break; } } if (!isByteSwap) { RefMasks.clear(); } return isByteSwap; }
bool Scalarizer::visitShuffleVectorInst(ShuffleVectorInst &SVI) { VectorType *VT = dyn_cast<VectorType>(SVI.getType()); if (!VT) return false; unsigned NumElems = VT->getNumElements(); Scatterer Op0 = scatter(&SVI, SVI.getOperand(0)); Scatterer Op1 = scatter(&SVI, SVI.getOperand(1)); ValueVector Res; Res.resize(NumElems); for (unsigned I = 0; I < NumElems; ++I) { int Selector = SVI.getMaskValue(I); if (Selector < 0) Res[I] = UndefValue::get(VT->getElementType()); else if (unsigned(Selector) < Op0.size()) Res[I] = Op0[Selector]; else Res[I] = Op1[Selector - Op0.size()]; } gather(&SVI, Res); return true; }