1f22ef01cSRoman Divacky //===- InstCombineVectorOps.cpp -------------------------------------------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This file implements instcombine for ExtractElement, InsertElement and 11f22ef01cSRoman Divacky // ShuffleVector. 12f22ef01cSRoman Divacky // 13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 14f22ef01cSRoman Divacky 15f22ef01cSRoman Divacky #include "InstCombine.h" 16f22ef01cSRoman Divacky using namespace llvm; 17f22ef01cSRoman Divacky 18f22ef01cSRoman Divacky /// CheapToScalarize - Return true if the value is cheaper to scalarize than it 19f22ef01cSRoman Divacky /// is to leave as a vector operation. 20f22ef01cSRoman Divacky static bool CheapToScalarize(Value *V, bool isConstant) { 21f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(V)) 22f22ef01cSRoman Divacky return true; 23f22ef01cSRoman Divacky if (ConstantVector *C = dyn_cast<ConstantVector>(V)) { 24f22ef01cSRoman Divacky if (isConstant) return true; 25f22ef01cSRoman Divacky // If all elts are the same, we can extract. 26f22ef01cSRoman Divacky Constant *Op0 = C->getOperand(0); 27f22ef01cSRoman Divacky for (unsigned i = 1; i < C->getNumOperands(); ++i) 28f22ef01cSRoman Divacky if (C->getOperand(i) != Op0) 29f22ef01cSRoman Divacky return false; 30f22ef01cSRoman Divacky return true; 31f22ef01cSRoman Divacky } 32f22ef01cSRoman Divacky Instruction *I = dyn_cast<Instruction>(V); 33f22ef01cSRoman Divacky if (!I) return false; 34f22ef01cSRoman Divacky 35f22ef01cSRoman Divacky // Insert element gets simplified to the inserted element or is deleted if 36f22ef01cSRoman Divacky // this is constant idx extract element and its a constant idx insertelt. 37f22ef01cSRoman Divacky if (I->getOpcode() == Instruction::InsertElement && isConstant && 38f22ef01cSRoman Divacky isa<ConstantInt>(I->getOperand(2))) 39f22ef01cSRoman Divacky return true; 40f22ef01cSRoman Divacky if (I->getOpcode() == Instruction::Load && I->hasOneUse()) 41f22ef01cSRoman Divacky return true; 42f22ef01cSRoman Divacky if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) 43f22ef01cSRoman Divacky if (BO->hasOneUse() && 44f22ef01cSRoman Divacky (CheapToScalarize(BO->getOperand(0), isConstant) || 45f22ef01cSRoman Divacky CheapToScalarize(BO->getOperand(1), isConstant))) 46f22ef01cSRoman Divacky return true; 47f22ef01cSRoman Divacky if (CmpInst *CI = dyn_cast<CmpInst>(I)) 48f22ef01cSRoman Divacky if (CI->hasOneUse() && 49f22ef01cSRoman Divacky (CheapToScalarize(CI->getOperand(0), isConstant) || 50f22ef01cSRoman Divacky CheapToScalarize(CI->getOperand(1), isConstant))) 51f22ef01cSRoman Divacky return true; 52f22ef01cSRoman Divacky 53f22ef01cSRoman Divacky return false; 54f22ef01cSRoman Divacky } 55f22ef01cSRoman Divacky 56f22ef01cSRoman Divacky /// Read and decode a shufflevector mask. 57f22ef01cSRoman Divacky /// 58f22ef01cSRoman Divacky /// It turns undef elements into values that are larger than the number of 59f22ef01cSRoman Divacky /// elements in the input. 60f22ef01cSRoman Divacky static std::vector<unsigned> getShuffleMask(const ShuffleVectorInst *SVI) { 61f22ef01cSRoman Divacky unsigned NElts = SVI->getType()->getNumElements(); 62f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(SVI->getOperand(2))) 63f22ef01cSRoman Divacky return std::vector<unsigned>(NElts, 0); 64f22ef01cSRoman Divacky if (isa<UndefValue>(SVI->getOperand(2))) 65f22ef01cSRoman Divacky return std::vector<unsigned>(NElts, 2*NElts); 66f22ef01cSRoman Divacky 67f22ef01cSRoman Divacky std::vector<unsigned> Result; 68f22ef01cSRoman Divacky const ConstantVector *CP = cast<ConstantVector>(SVI->getOperand(2)); 69f22ef01cSRoman Divacky for (User::const_op_iterator i = CP->op_begin(), e = CP->op_end(); i!=e; ++i) 70f22ef01cSRoman Divacky if (isa<UndefValue>(*i)) 71f22ef01cSRoman Divacky Result.push_back(NElts*2); // undef -> 8 72f22ef01cSRoman Divacky else 73f22ef01cSRoman Divacky Result.push_back(cast<ConstantInt>(*i)->getZExtValue()); 74f22ef01cSRoman Divacky return Result; 75f22ef01cSRoman Divacky } 76f22ef01cSRoman Divacky 77f22ef01cSRoman Divacky /// FindScalarElement - Given a vector and an element number, see if the scalar 78f22ef01cSRoman Divacky /// value is already around as a register, for example if it were inserted then 79f22ef01cSRoman Divacky /// extracted from the vector. 80f22ef01cSRoman Divacky static Value *FindScalarElement(Value *V, unsigned EltNo) { 81f22ef01cSRoman Divacky assert(V->getType()->isVectorTy() && "Not looking at a vector?"); 82f22ef01cSRoman Divacky const VectorType *PTy = cast<VectorType>(V->getType()); 83f22ef01cSRoman Divacky unsigned Width = PTy->getNumElements(); 84f22ef01cSRoman Divacky if (EltNo >= Width) // Out of range access. 85f22ef01cSRoman Divacky return UndefValue::get(PTy->getElementType()); 86f22ef01cSRoman Divacky 87f22ef01cSRoman Divacky if (isa<UndefValue>(V)) 88f22ef01cSRoman Divacky return UndefValue::get(PTy->getElementType()); 89f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(V)) 90f22ef01cSRoman Divacky return Constant::getNullValue(PTy->getElementType()); 91f22ef01cSRoman Divacky if (ConstantVector *CP = dyn_cast<ConstantVector>(V)) 92f22ef01cSRoman Divacky return CP->getOperand(EltNo); 93f22ef01cSRoman Divacky 94f22ef01cSRoman Divacky if (InsertElementInst *III = dyn_cast<InsertElementInst>(V)) { 95f22ef01cSRoman Divacky // If this is an insert to a variable element, we don't know what it is. 96f22ef01cSRoman Divacky if (!isa<ConstantInt>(III->getOperand(2))) 97f22ef01cSRoman Divacky return 0; 98f22ef01cSRoman Divacky unsigned IIElt = cast<ConstantInt>(III->getOperand(2))->getZExtValue(); 99f22ef01cSRoman Divacky 100f22ef01cSRoman Divacky // If this is an insert to the element we are looking for, return the 101f22ef01cSRoman Divacky // inserted value. 102f22ef01cSRoman Divacky if (EltNo == IIElt) 103f22ef01cSRoman Divacky return III->getOperand(1); 104f22ef01cSRoman Divacky 105f22ef01cSRoman Divacky // Otherwise, the insertelement doesn't modify the value, recurse on its 106f22ef01cSRoman Divacky // vector input. 107f22ef01cSRoman Divacky return FindScalarElement(III->getOperand(0), EltNo); 108f22ef01cSRoman Divacky } 109f22ef01cSRoman Divacky 110f22ef01cSRoman Divacky if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(V)) { 111f22ef01cSRoman Divacky unsigned LHSWidth = 112f22ef01cSRoman Divacky cast<VectorType>(SVI->getOperand(0)->getType())->getNumElements(); 113f22ef01cSRoman Divacky unsigned InEl = getShuffleMask(SVI)[EltNo]; 114f22ef01cSRoman Divacky if (InEl < LHSWidth) 115f22ef01cSRoman Divacky return FindScalarElement(SVI->getOperand(0), InEl); 116f22ef01cSRoman Divacky else if (InEl < LHSWidth*2) 117f22ef01cSRoman Divacky return FindScalarElement(SVI->getOperand(1), InEl - LHSWidth); 118f22ef01cSRoman Divacky else 119f22ef01cSRoman Divacky return UndefValue::get(PTy->getElementType()); 120f22ef01cSRoman Divacky } 121f22ef01cSRoman Divacky 122f22ef01cSRoman Divacky // Otherwise, we don't know. 123f22ef01cSRoman Divacky return 0; 124f22ef01cSRoman Divacky } 125f22ef01cSRoman Divacky 126f22ef01cSRoman Divacky Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { 127f22ef01cSRoman Divacky // If vector val is undef, replace extract with scalar undef. 128f22ef01cSRoman Divacky if (isa<UndefValue>(EI.getOperand(0))) 129f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 130f22ef01cSRoman Divacky 131f22ef01cSRoman Divacky // If vector val is constant 0, replace extract with scalar 0. 132f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(EI.getOperand(0))) 133f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, Constant::getNullValue(EI.getType())); 134f22ef01cSRoman Divacky 135f22ef01cSRoman Divacky if (ConstantVector *C = dyn_cast<ConstantVector>(EI.getOperand(0))) { 136f22ef01cSRoman Divacky // If vector val is constant with all elements the same, replace EI with 137f22ef01cSRoman Divacky // that element. When the elements are not identical, we cannot replace yet 138f22ef01cSRoman Divacky // (we do that below, but only when the index is constant). 139f22ef01cSRoman Divacky Constant *op0 = C->getOperand(0); 140f22ef01cSRoman Divacky for (unsigned i = 1; i != C->getNumOperands(); ++i) 141f22ef01cSRoman Divacky if (C->getOperand(i) != op0) { 142f22ef01cSRoman Divacky op0 = 0; 143f22ef01cSRoman Divacky break; 144f22ef01cSRoman Divacky } 145f22ef01cSRoman Divacky if (op0) 146f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, op0); 147f22ef01cSRoman Divacky } 148f22ef01cSRoman Divacky 149f22ef01cSRoman Divacky // If extracting a specified index from the vector, see if we can recursively 150f22ef01cSRoman Divacky // find a previously computed scalar that was inserted into the vector. 151f22ef01cSRoman Divacky if (ConstantInt *IdxC = dyn_cast<ConstantInt>(EI.getOperand(1))) { 152f22ef01cSRoman Divacky unsigned IndexVal = IdxC->getZExtValue(); 153f22ef01cSRoman Divacky unsigned VectorWidth = EI.getVectorOperandType()->getNumElements(); 154f22ef01cSRoman Divacky 155f22ef01cSRoman Divacky // If this is extracting an invalid index, turn this into undef, to avoid 156f22ef01cSRoman Divacky // crashing the code below. 157f22ef01cSRoman Divacky if (IndexVal >= VectorWidth) 158f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 159f22ef01cSRoman Divacky 160f22ef01cSRoman Divacky // This instruction only demands the single element from the input vector. 161f22ef01cSRoman Divacky // If the input vector has a single use, simplify it based on this use 162f22ef01cSRoman Divacky // property. 163f22ef01cSRoman Divacky if (EI.getOperand(0)->hasOneUse() && VectorWidth != 1) { 164f22ef01cSRoman Divacky APInt UndefElts(VectorWidth, 0); 165f22ef01cSRoman Divacky APInt DemandedMask(VectorWidth, 0); 166f22ef01cSRoman Divacky DemandedMask.set(IndexVal); 167f22ef01cSRoman Divacky if (Value *V = SimplifyDemandedVectorElts(EI.getOperand(0), 168f22ef01cSRoman Divacky DemandedMask, UndefElts)) { 169f22ef01cSRoman Divacky EI.setOperand(0, V); 170f22ef01cSRoman Divacky return &EI; 171f22ef01cSRoman Divacky } 172f22ef01cSRoman Divacky } 173f22ef01cSRoman Divacky 174f22ef01cSRoman Divacky if (Value *Elt = FindScalarElement(EI.getOperand(0), IndexVal)) 175f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, Elt); 176f22ef01cSRoman Divacky 177f22ef01cSRoman Divacky // If the this extractelement is directly using a bitcast from a vector of 178f22ef01cSRoman Divacky // the same number of elements, see if we can find the source element from 179f22ef01cSRoman Divacky // it. In this case, we will end up needing to bitcast the scalars. 180f22ef01cSRoman Divacky if (BitCastInst *BCI = dyn_cast<BitCastInst>(EI.getOperand(0))) { 181f22ef01cSRoman Divacky if (const VectorType *VT = 182f22ef01cSRoman Divacky dyn_cast<VectorType>(BCI->getOperand(0)->getType())) 183f22ef01cSRoman Divacky if (VT->getNumElements() == VectorWidth) 184f22ef01cSRoman Divacky if (Value *Elt = FindScalarElement(BCI->getOperand(0), IndexVal)) 185f22ef01cSRoman Divacky return new BitCastInst(Elt, EI.getType()); 186f22ef01cSRoman Divacky } 187f22ef01cSRoman Divacky } 188f22ef01cSRoman Divacky 189f22ef01cSRoman Divacky if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0))) { 190f22ef01cSRoman Divacky // Push extractelement into predecessor operation if legal and 191f22ef01cSRoman Divacky // profitable to do so 192f22ef01cSRoman Divacky if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 193f22ef01cSRoman Divacky if (I->hasOneUse() && 194f22ef01cSRoman Divacky CheapToScalarize(BO, isa<ConstantInt>(EI.getOperand(1)))) { 195f22ef01cSRoman Divacky Value *newEI0 = 196f22ef01cSRoman Divacky Builder->CreateExtractElement(BO->getOperand(0), EI.getOperand(1), 197f22ef01cSRoman Divacky EI.getName()+".lhs"); 198f22ef01cSRoman Divacky Value *newEI1 = 199f22ef01cSRoman Divacky Builder->CreateExtractElement(BO->getOperand(1), EI.getOperand(1), 200f22ef01cSRoman Divacky EI.getName()+".rhs"); 201f22ef01cSRoman Divacky return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1); 202f22ef01cSRoman Divacky } 203f22ef01cSRoman Divacky } else if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) { 204f22ef01cSRoman Divacky // Extracting the inserted element? 205f22ef01cSRoman Divacky if (IE->getOperand(2) == EI.getOperand(1)) 206f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, IE->getOperand(1)); 207f22ef01cSRoman Divacky // If the inserted and extracted elements are constants, they must not 208f22ef01cSRoman Divacky // be the same value, extract from the pre-inserted value instead. 209f22ef01cSRoman Divacky if (isa<Constant>(IE->getOperand(2)) && isa<Constant>(EI.getOperand(1))) { 210f22ef01cSRoman Divacky Worklist.AddValue(EI.getOperand(0)); 211f22ef01cSRoman Divacky EI.setOperand(0, IE->getOperand(0)); 212f22ef01cSRoman Divacky return &EI; 213f22ef01cSRoman Divacky } 214f22ef01cSRoman Divacky } else if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I)) { 215f22ef01cSRoman Divacky // If this is extracting an element from a shufflevector, figure out where 216f22ef01cSRoman Divacky // it came from and extract from the appropriate input element instead. 217f22ef01cSRoman Divacky if (ConstantInt *Elt = dyn_cast<ConstantInt>(EI.getOperand(1))) { 218f22ef01cSRoman Divacky unsigned SrcIdx = getShuffleMask(SVI)[Elt->getZExtValue()]; 219f22ef01cSRoman Divacky Value *Src; 220f22ef01cSRoman Divacky unsigned LHSWidth = 221f22ef01cSRoman Divacky cast<VectorType>(SVI->getOperand(0)->getType())->getNumElements(); 222f22ef01cSRoman Divacky 223f22ef01cSRoman Divacky if (SrcIdx < LHSWidth) 224f22ef01cSRoman Divacky Src = SVI->getOperand(0); 225f22ef01cSRoman Divacky else if (SrcIdx < LHSWidth*2) { 226f22ef01cSRoman Divacky SrcIdx -= LHSWidth; 227f22ef01cSRoman Divacky Src = SVI->getOperand(1); 228f22ef01cSRoman Divacky } else { 229f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 230f22ef01cSRoman Divacky } 231f22ef01cSRoman Divacky return ExtractElementInst::Create(Src, 232f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(EI.getContext()), 233f22ef01cSRoman Divacky SrcIdx, false)); 234f22ef01cSRoman Divacky } 235f22ef01cSRoman Divacky } 236f22ef01cSRoman Divacky // FIXME: Canonicalize extractelement(bitcast) -> bitcast(extractelement) 237f22ef01cSRoman Divacky } 238f22ef01cSRoman Divacky return 0; 239f22ef01cSRoman Divacky } 240f22ef01cSRoman Divacky 241f22ef01cSRoman Divacky /// CollectSingleShuffleElements - If V is a shuffle of values that ONLY returns 242f22ef01cSRoman Divacky /// elements from either LHS or RHS, return the shuffle mask and true. 243f22ef01cSRoman Divacky /// Otherwise, return false. 244f22ef01cSRoman Divacky static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS, 245f22ef01cSRoman Divacky std::vector<Constant*> &Mask) { 246f22ef01cSRoman Divacky assert(V->getType() == LHS->getType() && V->getType() == RHS->getType() && 247f22ef01cSRoman Divacky "Invalid CollectSingleShuffleElements"); 248f22ef01cSRoman Divacky unsigned NumElts = cast<VectorType>(V->getType())->getNumElements(); 249f22ef01cSRoman Divacky 250f22ef01cSRoman Divacky if (isa<UndefValue>(V)) { 251f22ef01cSRoman Divacky Mask.assign(NumElts, UndefValue::get(Type::getInt32Ty(V->getContext()))); 252f22ef01cSRoman Divacky return true; 253f22ef01cSRoman Divacky } 254f22ef01cSRoman Divacky 255f22ef01cSRoman Divacky if (V == LHS) { 256f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) 257f22ef01cSRoman Divacky Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), i)); 258f22ef01cSRoman Divacky return true; 259f22ef01cSRoman Divacky } 260f22ef01cSRoman Divacky 261f22ef01cSRoman Divacky if (V == RHS) { 262f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) 263f22ef01cSRoman Divacky Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), 264f22ef01cSRoman Divacky i+NumElts)); 265f22ef01cSRoman Divacky return true; 266f22ef01cSRoman Divacky } 267f22ef01cSRoman Divacky 268f22ef01cSRoman Divacky if (InsertElementInst *IEI = dyn_cast<InsertElementInst>(V)) { 269f22ef01cSRoman Divacky // If this is an insert of an extract from some other vector, include it. 270f22ef01cSRoman Divacky Value *VecOp = IEI->getOperand(0); 271f22ef01cSRoman Divacky Value *ScalarOp = IEI->getOperand(1); 272f22ef01cSRoman Divacky Value *IdxOp = IEI->getOperand(2); 273f22ef01cSRoman Divacky 274f22ef01cSRoman Divacky if (!isa<ConstantInt>(IdxOp)) 275f22ef01cSRoman Divacky return false; 276f22ef01cSRoman Divacky unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 277f22ef01cSRoman Divacky 278f22ef01cSRoman Divacky if (isa<UndefValue>(ScalarOp)) { // inserting undef into vector. 279f22ef01cSRoman Divacky // Okay, we can handle this if the vector we are insertinting into is 280f22ef01cSRoman Divacky // transitively ok. 281f22ef01cSRoman Divacky if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) { 282f22ef01cSRoman Divacky // If so, update the mask to reflect the inserted undef. 283f22ef01cSRoman Divacky Mask[InsertedIdx] = UndefValue::get(Type::getInt32Ty(V->getContext())); 284f22ef01cSRoman Divacky return true; 285f22ef01cSRoman Divacky } 286f22ef01cSRoman Divacky } else if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)){ 287f22ef01cSRoman Divacky if (isa<ConstantInt>(EI->getOperand(1)) && 288f22ef01cSRoman Divacky EI->getOperand(0)->getType() == V->getType()) { 289f22ef01cSRoman Divacky unsigned ExtractedIdx = 290f22ef01cSRoman Divacky cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 291f22ef01cSRoman Divacky 292f22ef01cSRoman Divacky // This must be extracting from either LHS or RHS. 293f22ef01cSRoman Divacky if (EI->getOperand(0) == LHS || EI->getOperand(0) == RHS) { 294f22ef01cSRoman Divacky // Okay, we can handle this if the vector we are insertinting into is 295f22ef01cSRoman Divacky // transitively ok. 296f22ef01cSRoman Divacky if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) { 297f22ef01cSRoman Divacky // If so, update the mask to reflect the inserted value. 298f22ef01cSRoman Divacky if (EI->getOperand(0) == LHS) { 299f22ef01cSRoman Divacky Mask[InsertedIdx % NumElts] = 300f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(V->getContext()), 301f22ef01cSRoman Divacky ExtractedIdx); 302f22ef01cSRoman Divacky } else { 303f22ef01cSRoman Divacky assert(EI->getOperand(0) == RHS); 304f22ef01cSRoman Divacky Mask[InsertedIdx % NumElts] = 305f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(V->getContext()), 306f22ef01cSRoman Divacky ExtractedIdx+NumElts); 307f22ef01cSRoman Divacky 308f22ef01cSRoman Divacky } 309f22ef01cSRoman Divacky return true; 310f22ef01cSRoman Divacky } 311f22ef01cSRoman Divacky } 312f22ef01cSRoman Divacky } 313f22ef01cSRoman Divacky } 314f22ef01cSRoman Divacky } 315f22ef01cSRoman Divacky // TODO: Handle shufflevector here! 316f22ef01cSRoman Divacky 317f22ef01cSRoman Divacky return false; 318f22ef01cSRoman Divacky } 319f22ef01cSRoman Divacky 320f22ef01cSRoman Divacky /// CollectShuffleElements - We are building a shuffle of V, using RHS as the 321f22ef01cSRoman Divacky /// RHS of the shuffle instruction, if it is not null. Return a shuffle mask 322f22ef01cSRoman Divacky /// that computes V and the LHS value of the shuffle. 323f22ef01cSRoman Divacky static Value *CollectShuffleElements(Value *V, std::vector<Constant*> &Mask, 324f22ef01cSRoman Divacky Value *&RHS) { 325f22ef01cSRoman Divacky assert(V->getType()->isVectorTy() && 326f22ef01cSRoman Divacky (RHS == 0 || V->getType() == RHS->getType()) && 327f22ef01cSRoman Divacky "Invalid shuffle!"); 328f22ef01cSRoman Divacky unsigned NumElts = cast<VectorType>(V->getType())->getNumElements(); 329f22ef01cSRoman Divacky 330f22ef01cSRoman Divacky if (isa<UndefValue>(V)) { 331f22ef01cSRoman Divacky Mask.assign(NumElts, UndefValue::get(Type::getInt32Ty(V->getContext()))); 332f22ef01cSRoman Divacky return V; 333f22ef01cSRoman Divacky } else if (isa<ConstantAggregateZero>(V)) { 334f22ef01cSRoman Divacky Mask.assign(NumElts, ConstantInt::get(Type::getInt32Ty(V->getContext()),0)); 335f22ef01cSRoman Divacky return V; 336f22ef01cSRoman Divacky } else if (InsertElementInst *IEI = dyn_cast<InsertElementInst>(V)) { 337f22ef01cSRoman Divacky // If this is an insert of an extract from some other vector, include it. 338f22ef01cSRoman Divacky Value *VecOp = IEI->getOperand(0); 339f22ef01cSRoman Divacky Value *ScalarOp = IEI->getOperand(1); 340f22ef01cSRoman Divacky Value *IdxOp = IEI->getOperand(2); 341f22ef01cSRoman Divacky 342f22ef01cSRoman Divacky if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) { 343f22ef01cSRoman Divacky if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) && 344f22ef01cSRoman Divacky EI->getOperand(0)->getType() == V->getType()) { 345f22ef01cSRoman Divacky unsigned ExtractedIdx = 346f22ef01cSRoman Divacky cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 347f22ef01cSRoman Divacky unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 348f22ef01cSRoman Divacky 349f22ef01cSRoman Divacky // Either the extracted from or inserted into vector must be RHSVec, 350f22ef01cSRoman Divacky // otherwise we'd end up with a shuffle of three inputs. 351f22ef01cSRoman Divacky if (EI->getOperand(0) == RHS || RHS == 0) { 352f22ef01cSRoman Divacky RHS = EI->getOperand(0); 353f22ef01cSRoman Divacky Value *V = CollectShuffleElements(VecOp, Mask, RHS); 354f22ef01cSRoman Divacky Mask[InsertedIdx % NumElts] = 355f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(V->getContext()), 356f22ef01cSRoman Divacky NumElts+ExtractedIdx); 357f22ef01cSRoman Divacky return V; 358f22ef01cSRoman Divacky } 359f22ef01cSRoman Divacky 360f22ef01cSRoman Divacky if (VecOp == RHS) { 361f22ef01cSRoman Divacky Value *V = CollectShuffleElements(EI->getOperand(0), Mask, RHS); 362f22ef01cSRoman Divacky // Everything but the extracted element is replaced with the RHS. 363f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) { 364f22ef01cSRoman Divacky if (i != InsertedIdx) 365f22ef01cSRoman Divacky Mask[i] = ConstantInt::get(Type::getInt32Ty(V->getContext()), 366f22ef01cSRoman Divacky NumElts+i); 367f22ef01cSRoman Divacky } 368f22ef01cSRoman Divacky return V; 369f22ef01cSRoman Divacky } 370f22ef01cSRoman Divacky 371f22ef01cSRoman Divacky // If this insertelement is a chain that comes from exactly these two 372f22ef01cSRoman Divacky // vectors, return the vector and the effective shuffle. 373f22ef01cSRoman Divacky if (CollectSingleShuffleElements(IEI, EI->getOperand(0), RHS, Mask)) 374f22ef01cSRoman Divacky return EI->getOperand(0); 375f22ef01cSRoman Divacky } 376f22ef01cSRoman Divacky } 377f22ef01cSRoman Divacky } 378f22ef01cSRoman Divacky // TODO: Handle shufflevector here! 379f22ef01cSRoman Divacky 380f22ef01cSRoman Divacky // Otherwise, can't do anything fancy. Return an identity vector. 381f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) 382f22ef01cSRoman Divacky Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), i)); 383f22ef01cSRoman Divacky return V; 384f22ef01cSRoman Divacky } 385f22ef01cSRoman Divacky 386f22ef01cSRoman Divacky Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { 387f22ef01cSRoman Divacky Value *VecOp = IE.getOperand(0); 388f22ef01cSRoman Divacky Value *ScalarOp = IE.getOperand(1); 389f22ef01cSRoman Divacky Value *IdxOp = IE.getOperand(2); 390f22ef01cSRoman Divacky 391f22ef01cSRoman Divacky // Inserting an undef or into an undefined place, remove this. 392f22ef01cSRoman Divacky if (isa<UndefValue>(ScalarOp) || isa<UndefValue>(IdxOp)) 393f22ef01cSRoman Divacky ReplaceInstUsesWith(IE, VecOp); 394f22ef01cSRoman Divacky 395f22ef01cSRoman Divacky // If the inserted element was extracted from some other vector, and if the 396f22ef01cSRoman Divacky // indexes are constant, try to turn this into a shufflevector operation. 397f22ef01cSRoman Divacky if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) { 398f22ef01cSRoman Divacky if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) && 399f22ef01cSRoman Divacky EI->getOperand(0)->getType() == IE.getType()) { 400f22ef01cSRoman Divacky unsigned NumVectorElts = IE.getType()->getNumElements(); 401f22ef01cSRoman Divacky unsigned ExtractedIdx = 402f22ef01cSRoman Divacky cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 403f22ef01cSRoman Divacky unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 404f22ef01cSRoman Divacky 405f22ef01cSRoman Divacky if (ExtractedIdx >= NumVectorElts) // Out of range extract. 406f22ef01cSRoman Divacky return ReplaceInstUsesWith(IE, VecOp); 407f22ef01cSRoman Divacky 408f22ef01cSRoman Divacky if (InsertedIdx >= NumVectorElts) // Out of range insert. 409f22ef01cSRoman Divacky return ReplaceInstUsesWith(IE, UndefValue::get(IE.getType())); 410f22ef01cSRoman Divacky 411f22ef01cSRoman Divacky // If we are extracting a value from a vector, then inserting it right 412f22ef01cSRoman Divacky // back into the same place, just use the input vector. 413f22ef01cSRoman Divacky if (EI->getOperand(0) == VecOp && ExtractedIdx == InsertedIdx) 414f22ef01cSRoman Divacky return ReplaceInstUsesWith(IE, VecOp); 415f22ef01cSRoman Divacky 416f22ef01cSRoman Divacky // If this insertelement isn't used by some other insertelement, turn it 417f22ef01cSRoman Divacky // (and any insertelements it points to), into one big shuffle. 418f22ef01cSRoman Divacky if (!IE.hasOneUse() || !isa<InsertElementInst>(IE.use_back())) { 419f22ef01cSRoman Divacky std::vector<Constant*> Mask; 420f22ef01cSRoman Divacky Value *RHS = 0; 421f22ef01cSRoman Divacky Value *LHS = CollectShuffleElements(&IE, Mask, RHS); 422f22ef01cSRoman Divacky if (RHS == 0) RHS = UndefValue::get(LHS->getType()); 423f22ef01cSRoman Divacky // We now have a shuffle of LHS, RHS, Mask. 424f22ef01cSRoman Divacky return new ShuffleVectorInst(LHS, RHS, 425f22ef01cSRoman Divacky ConstantVector::get(Mask)); 426f22ef01cSRoman Divacky } 427f22ef01cSRoman Divacky } 428f22ef01cSRoman Divacky } 429f22ef01cSRoman Divacky 430f22ef01cSRoman Divacky unsigned VWidth = cast<VectorType>(VecOp->getType())->getNumElements(); 431f22ef01cSRoman Divacky APInt UndefElts(VWidth, 0); 432f22ef01cSRoman Divacky APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); 433f22ef01cSRoman Divacky if (SimplifyDemandedVectorElts(&IE, AllOnesEltMask, UndefElts)) 434f22ef01cSRoman Divacky return &IE; 435f22ef01cSRoman Divacky 436f22ef01cSRoman Divacky return 0; 437f22ef01cSRoman Divacky } 438f22ef01cSRoman Divacky 439f22ef01cSRoman Divacky 440f22ef01cSRoman Divacky Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { 441f22ef01cSRoman Divacky Value *LHS = SVI.getOperand(0); 442f22ef01cSRoman Divacky Value *RHS = SVI.getOperand(1); 443f22ef01cSRoman Divacky std::vector<unsigned> Mask = getShuffleMask(&SVI); 444f22ef01cSRoman Divacky 445f22ef01cSRoman Divacky bool MadeChange = false; 446f22ef01cSRoman Divacky 447f22ef01cSRoman Divacky // Undefined shuffle mask -> undefined value. 448f22ef01cSRoman Divacky if (isa<UndefValue>(SVI.getOperand(2))) 449f22ef01cSRoman Divacky return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType())); 450f22ef01cSRoman Divacky 451f22ef01cSRoman Divacky unsigned VWidth = cast<VectorType>(SVI.getType())->getNumElements(); 452f22ef01cSRoman Divacky 453f22ef01cSRoman Divacky if (VWidth != cast<VectorType>(LHS->getType())->getNumElements()) 454f22ef01cSRoman Divacky return 0; 455f22ef01cSRoman Divacky 456f22ef01cSRoman Divacky APInt UndefElts(VWidth, 0); 457f22ef01cSRoman Divacky APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); 458f22ef01cSRoman Divacky if (SimplifyDemandedVectorElts(&SVI, AllOnesEltMask, UndefElts)) { 459f22ef01cSRoman Divacky LHS = SVI.getOperand(0); 460f22ef01cSRoman Divacky RHS = SVI.getOperand(1); 461f22ef01cSRoman Divacky MadeChange = true; 462f22ef01cSRoman Divacky } 463f22ef01cSRoman Divacky 464f22ef01cSRoman Divacky // Canonicalize shuffle(x ,x,mask) -> shuffle(x, undef,mask') 465f22ef01cSRoman Divacky // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask'). 466f22ef01cSRoman Divacky if (LHS == RHS || isa<UndefValue>(LHS)) { 467f22ef01cSRoman Divacky if (isa<UndefValue>(LHS) && LHS == RHS) { 468f22ef01cSRoman Divacky // shuffle(undef,undef,mask) -> undef. 469f22ef01cSRoman Divacky return ReplaceInstUsesWith(SVI, LHS); 470f22ef01cSRoman Divacky } 471f22ef01cSRoman Divacky 472f22ef01cSRoman Divacky // Remap any references to RHS to use LHS. 473f22ef01cSRoman Divacky std::vector<Constant*> Elts; 474f22ef01cSRoman Divacky for (unsigned i = 0, e = Mask.size(); i != e; ++i) { 475f22ef01cSRoman Divacky if (Mask[i] >= 2*e) 476f22ef01cSRoman Divacky Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); 477f22ef01cSRoman Divacky else { 478f22ef01cSRoman Divacky if ((Mask[i] >= e && isa<UndefValue>(RHS)) || 479f22ef01cSRoman Divacky (Mask[i] < e && isa<UndefValue>(LHS))) { 480f22ef01cSRoman Divacky Mask[i] = 2*e; // Turn into undef. 481f22ef01cSRoman Divacky Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); 482f22ef01cSRoman Divacky } else { 483f22ef01cSRoman Divacky Mask[i] = Mask[i] % e; // Force to LHS. 484f22ef01cSRoman Divacky Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()), 485f22ef01cSRoman Divacky Mask[i])); 486f22ef01cSRoman Divacky } 487f22ef01cSRoman Divacky } 488f22ef01cSRoman Divacky } 489f22ef01cSRoman Divacky SVI.setOperand(0, SVI.getOperand(1)); 490f22ef01cSRoman Divacky SVI.setOperand(1, UndefValue::get(RHS->getType())); 491f22ef01cSRoman Divacky SVI.setOperand(2, ConstantVector::get(Elts)); 492f22ef01cSRoman Divacky LHS = SVI.getOperand(0); 493f22ef01cSRoman Divacky RHS = SVI.getOperand(1); 494f22ef01cSRoman Divacky MadeChange = true; 495f22ef01cSRoman Divacky } 496f22ef01cSRoman Divacky 497f22ef01cSRoman Divacky // Analyze the shuffle, are the LHS or RHS and identity shuffles? 498f22ef01cSRoman Divacky bool isLHSID = true, isRHSID = true; 499f22ef01cSRoman Divacky 500f22ef01cSRoman Divacky for (unsigned i = 0, e = Mask.size(); i != e; ++i) { 501f22ef01cSRoman Divacky if (Mask[i] >= e*2) continue; // Ignore undef values. 502f22ef01cSRoman Divacky // Is this an identity shuffle of the LHS value? 503f22ef01cSRoman Divacky isLHSID &= (Mask[i] == i); 504f22ef01cSRoman Divacky 505f22ef01cSRoman Divacky // Is this an identity shuffle of the RHS value? 506f22ef01cSRoman Divacky isRHSID &= (Mask[i]-e == i); 507f22ef01cSRoman Divacky } 508f22ef01cSRoman Divacky 509f22ef01cSRoman Divacky // Eliminate identity shuffles. 510f22ef01cSRoman Divacky if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); 511f22ef01cSRoman Divacky if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); 512f22ef01cSRoman Divacky 513f22ef01cSRoman Divacky // If the LHS is a shufflevector itself, see if we can combine it with this 514f22ef01cSRoman Divacky // one without producing an unusual shuffle. Here we are really conservative: 515f22ef01cSRoman Divacky // we are absolutely afraid of producing a shuffle mask not in the input 516f22ef01cSRoman Divacky // program, because the code gen may not be smart enough to turn a merged 517f22ef01cSRoman Divacky // shuffle into two specific shuffles: it may produce worse code. As such, 518f22ef01cSRoman Divacky // we only merge two shuffles if the result is one of the two input shuffle 519f22ef01cSRoman Divacky // masks. In this case, merging the shuffles just removes one instruction, 520f22ef01cSRoman Divacky // which we know is safe. This is good for things like turning: 521f22ef01cSRoman Divacky // (splat(splat)) -> splat. 522f22ef01cSRoman Divacky if (ShuffleVectorInst *LHSSVI = dyn_cast<ShuffleVectorInst>(LHS)) { 523f22ef01cSRoman Divacky if (isa<UndefValue>(RHS)) { 524f22ef01cSRoman Divacky std::vector<unsigned> LHSMask = getShuffleMask(LHSSVI); 525f22ef01cSRoman Divacky 526f22ef01cSRoman Divacky if (LHSMask.size() == Mask.size()) { 527f22ef01cSRoman Divacky std::vector<unsigned> NewMask; 528f22ef01cSRoman Divacky for (unsigned i = 0, e = Mask.size(); i != e; ++i) 529f22ef01cSRoman Divacky if (Mask[i] >= e) 530f22ef01cSRoman Divacky NewMask.push_back(2*e); 531f22ef01cSRoman Divacky else 532f22ef01cSRoman Divacky NewMask.push_back(LHSMask[Mask[i]]); 533f22ef01cSRoman Divacky 534f22ef01cSRoman Divacky // If the result mask is equal to the src shuffle or this 535f22ef01cSRoman Divacky // shuffle mask, do the replacement. 536f22ef01cSRoman Divacky if (NewMask == LHSMask || NewMask == Mask) { 537f22ef01cSRoman Divacky unsigned LHSInNElts = 538f22ef01cSRoman Divacky cast<VectorType>(LHSSVI->getOperand(0)->getType())-> 539f22ef01cSRoman Divacky getNumElements(); 540f22ef01cSRoman Divacky std::vector<Constant*> Elts; 541f22ef01cSRoman Divacky for (unsigned i = 0, e = NewMask.size(); i != e; ++i) { 542f22ef01cSRoman Divacky if (NewMask[i] >= LHSInNElts*2) { 543f22ef01cSRoman Divacky Elts.push_back(UndefValue::get( 544f22ef01cSRoman Divacky Type::getInt32Ty(SVI.getContext()))); 545f22ef01cSRoman Divacky } else { 546f22ef01cSRoman Divacky Elts.push_back(ConstantInt::get( 547f22ef01cSRoman Divacky Type::getInt32Ty(SVI.getContext()), 548f22ef01cSRoman Divacky NewMask[i])); 549f22ef01cSRoman Divacky } 550f22ef01cSRoman Divacky } 551f22ef01cSRoman Divacky return new ShuffleVectorInst(LHSSVI->getOperand(0), 552f22ef01cSRoman Divacky LHSSVI->getOperand(1), 553f22ef01cSRoman Divacky ConstantVector::get(Elts)); 554f22ef01cSRoman Divacky } 555f22ef01cSRoman Divacky } 556f22ef01cSRoman Divacky } 557f22ef01cSRoman Divacky } 558f22ef01cSRoman Divacky 559f22ef01cSRoman Divacky return MadeChange ? &SVI : 0; 560f22ef01cSRoman Divacky } 561f22ef01cSRoman Divacky 562