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 562754fe60SDimitry Andric /// getShuffleMask - Read and decode a shufflevector mask. 572754fe60SDimitry Andric /// Turn undef elements into negative values. 582754fe60SDimitry Andric static std::vector<int> getShuffleMask(const ShuffleVectorInst *SVI) { 59f22ef01cSRoman Divacky unsigned NElts = SVI->getType()->getNumElements(); 60f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(SVI->getOperand(2))) 612754fe60SDimitry Andric return std::vector<int>(NElts, 0); 62f22ef01cSRoman Divacky if (isa<UndefValue>(SVI->getOperand(2))) 632754fe60SDimitry Andric return std::vector<int>(NElts, -1); 64f22ef01cSRoman Divacky 652754fe60SDimitry Andric std::vector<int> Result; 66f22ef01cSRoman Divacky const ConstantVector *CP = cast<ConstantVector>(SVI->getOperand(2)); 67f22ef01cSRoman Divacky for (User::const_op_iterator i = CP->op_begin(), e = CP->op_end(); i!=e; ++i) 68f22ef01cSRoman Divacky if (isa<UndefValue>(*i)) 692754fe60SDimitry Andric Result.push_back(-1); // undef 70f22ef01cSRoman Divacky else 71f22ef01cSRoman Divacky Result.push_back(cast<ConstantInt>(*i)->getZExtValue()); 72f22ef01cSRoman Divacky return Result; 73f22ef01cSRoman Divacky } 74f22ef01cSRoman Divacky 75f22ef01cSRoman Divacky /// FindScalarElement - Given a vector and an element number, see if the scalar 76f22ef01cSRoman Divacky /// value is already around as a register, for example if it were inserted then 77f22ef01cSRoman Divacky /// extracted from the vector. 78f22ef01cSRoman Divacky static Value *FindScalarElement(Value *V, unsigned EltNo) { 79f22ef01cSRoman Divacky assert(V->getType()->isVectorTy() && "Not looking at a vector?"); 80f22ef01cSRoman Divacky const VectorType *PTy = cast<VectorType>(V->getType()); 81f22ef01cSRoman Divacky unsigned Width = PTy->getNumElements(); 82f22ef01cSRoman Divacky if (EltNo >= Width) // Out of range access. 83f22ef01cSRoman Divacky return UndefValue::get(PTy->getElementType()); 84f22ef01cSRoman Divacky 85f22ef01cSRoman Divacky if (isa<UndefValue>(V)) 86f22ef01cSRoman Divacky return UndefValue::get(PTy->getElementType()); 87f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(V)) 88f22ef01cSRoman Divacky return Constant::getNullValue(PTy->getElementType()); 89f22ef01cSRoman Divacky if (ConstantVector *CP = dyn_cast<ConstantVector>(V)) 90f22ef01cSRoman Divacky return CP->getOperand(EltNo); 91f22ef01cSRoman Divacky 92f22ef01cSRoman Divacky if (InsertElementInst *III = dyn_cast<InsertElementInst>(V)) { 93f22ef01cSRoman Divacky // If this is an insert to a variable element, we don't know what it is. 94f22ef01cSRoman Divacky if (!isa<ConstantInt>(III->getOperand(2))) 95f22ef01cSRoman Divacky return 0; 96f22ef01cSRoman Divacky unsigned IIElt = cast<ConstantInt>(III->getOperand(2))->getZExtValue(); 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky // If this is an insert to the element we are looking for, return the 99f22ef01cSRoman Divacky // inserted value. 100f22ef01cSRoman Divacky if (EltNo == IIElt) 101f22ef01cSRoman Divacky return III->getOperand(1); 102f22ef01cSRoman Divacky 103f22ef01cSRoman Divacky // Otherwise, the insertelement doesn't modify the value, recurse on its 104f22ef01cSRoman Divacky // vector input. 105f22ef01cSRoman Divacky return FindScalarElement(III->getOperand(0), EltNo); 106f22ef01cSRoman Divacky } 107f22ef01cSRoman Divacky 108f22ef01cSRoman Divacky if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(V)) { 109f22ef01cSRoman Divacky unsigned LHSWidth = 110f22ef01cSRoman Divacky cast<VectorType>(SVI->getOperand(0)->getType())->getNumElements(); 1112754fe60SDimitry Andric int InEl = getShuffleMask(SVI)[EltNo]; 1122754fe60SDimitry Andric if (InEl < 0) 113f22ef01cSRoman Divacky return UndefValue::get(PTy->getElementType()); 1142754fe60SDimitry Andric if (InEl < (int)LHSWidth) 1152754fe60SDimitry Andric return FindScalarElement(SVI->getOperand(0), InEl); 1162754fe60SDimitry Andric return FindScalarElement(SVI->getOperand(1), InEl - LHSWidth); 117f22ef01cSRoman Divacky } 118f22ef01cSRoman Divacky 119f22ef01cSRoman Divacky // Otherwise, we don't know. 120f22ef01cSRoman Divacky return 0; 121f22ef01cSRoman Divacky } 122f22ef01cSRoman Divacky 123f22ef01cSRoman Divacky Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { 124f22ef01cSRoman Divacky // If vector val is undef, replace extract with scalar undef. 125f22ef01cSRoman Divacky if (isa<UndefValue>(EI.getOperand(0))) 126f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 127f22ef01cSRoman Divacky 128f22ef01cSRoman Divacky // If vector val is constant 0, replace extract with scalar 0. 129f22ef01cSRoman Divacky if (isa<ConstantAggregateZero>(EI.getOperand(0))) 130f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, Constant::getNullValue(EI.getType())); 131f22ef01cSRoman Divacky 132f22ef01cSRoman Divacky if (ConstantVector *C = dyn_cast<ConstantVector>(EI.getOperand(0))) { 133f22ef01cSRoman Divacky // If vector val is constant with all elements the same, replace EI with 134f22ef01cSRoman Divacky // that element. When the elements are not identical, we cannot replace yet 135f22ef01cSRoman Divacky // (we do that below, but only when the index is constant). 136f22ef01cSRoman Divacky Constant *op0 = C->getOperand(0); 137f22ef01cSRoman Divacky for (unsigned i = 1; i != C->getNumOperands(); ++i) 138f22ef01cSRoman Divacky if (C->getOperand(i) != op0) { 139f22ef01cSRoman Divacky op0 = 0; 140f22ef01cSRoman Divacky break; 141f22ef01cSRoman Divacky } 142f22ef01cSRoman Divacky if (op0) 143f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, op0); 144f22ef01cSRoman Divacky } 145f22ef01cSRoman Divacky 146f22ef01cSRoman Divacky // If extracting a specified index from the vector, see if we can recursively 147f22ef01cSRoman Divacky // find a previously computed scalar that was inserted into the vector. 148f22ef01cSRoman Divacky if (ConstantInt *IdxC = dyn_cast<ConstantInt>(EI.getOperand(1))) { 149f22ef01cSRoman Divacky unsigned IndexVal = IdxC->getZExtValue(); 150f22ef01cSRoman Divacky unsigned VectorWidth = EI.getVectorOperandType()->getNumElements(); 151f22ef01cSRoman Divacky 152f22ef01cSRoman Divacky // If this is extracting an invalid index, turn this into undef, to avoid 153f22ef01cSRoman Divacky // crashing the code below. 154f22ef01cSRoman Divacky if (IndexVal >= VectorWidth) 155f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 156f22ef01cSRoman Divacky 157f22ef01cSRoman Divacky // This instruction only demands the single element from the input vector. 158f22ef01cSRoman Divacky // If the input vector has a single use, simplify it based on this use 159f22ef01cSRoman Divacky // property. 160f22ef01cSRoman Divacky if (EI.getOperand(0)->hasOneUse() && VectorWidth != 1) { 161f22ef01cSRoman Divacky APInt UndefElts(VectorWidth, 0); 162f22ef01cSRoman Divacky APInt DemandedMask(VectorWidth, 0); 1632754fe60SDimitry Andric DemandedMask.setBit(IndexVal); 164f22ef01cSRoman Divacky if (Value *V = SimplifyDemandedVectorElts(EI.getOperand(0), 165f22ef01cSRoman Divacky DemandedMask, UndefElts)) { 166f22ef01cSRoman Divacky EI.setOperand(0, V); 167f22ef01cSRoman Divacky return &EI; 168f22ef01cSRoman Divacky } 169f22ef01cSRoman Divacky } 170f22ef01cSRoman Divacky 171f22ef01cSRoman Divacky if (Value *Elt = FindScalarElement(EI.getOperand(0), IndexVal)) 172f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, Elt); 173f22ef01cSRoman Divacky 174f22ef01cSRoman Divacky // If the this extractelement is directly using a bitcast from a vector of 175f22ef01cSRoman Divacky // the same number of elements, see if we can find the source element from 176f22ef01cSRoman Divacky // it. In this case, we will end up needing to bitcast the scalars. 177f22ef01cSRoman Divacky if (BitCastInst *BCI = dyn_cast<BitCastInst>(EI.getOperand(0))) { 178f22ef01cSRoman Divacky if (const VectorType *VT = 179f22ef01cSRoman Divacky dyn_cast<VectorType>(BCI->getOperand(0)->getType())) 180f22ef01cSRoman Divacky if (VT->getNumElements() == VectorWidth) 181f22ef01cSRoman Divacky if (Value *Elt = FindScalarElement(BCI->getOperand(0), IndexVal)) 182f22ef01cSRoman Divacky return new BitCastInst(Elt, EI.getType()); 183f22ef01cSRoman Divacky } 184f22ef01cSRoman Divacky } 185f22ef01cSRoman Divacky 186f22ef01cSRoman Divacky if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0))) { 187f22ef01cSRoman Divacky // Push extractelement into predecessor operation if legal and 188f22ef01cSRoman Divacky // profitable to do so 189f22ef01cSRoman Divacky if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 190f22ef01cSRoman Divacky if (I->hasOneUse() && 191f22ef01cSRoman Divacky CheapToScalarize(BO, isa<ConstantInt>(EI.getOperand(1)))) { 192f22ef01cSRoman Divacky Value *newEI0 = 193f22ef01cSRoman Divacky Builder->CreateExtractElement(BO->getOperand(0), EI.getOperand(1), 194f22ef01cSRoman Divacky EI.getName()+".lhs"); 195f22ef01cSRoman Divacky Value *newEI1 = 196f22ef01cSRoman Divacky Builder->CreateExtractElement(BO->getOperand(1), EI.getOperand(1), 197f22ef01cSRoman Divacky EI.getName()+".rhs"); 198f22ef01cSRoman Divacky return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1); 199f22ef01cSRoman Divacky } 200f22ef01cSRoman Divacky } else if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) { 201f22ef01cSRoman Divacky // Extracting the inserted element? 202f22ef01cSRoman Divacky if (IE->getOperand(2) == EI.getOperand(1)) 203f22ef01cSRoman Divacky return ReplaceInstUsesWith(EI, IE->getOperand(1)); 204f22ef01cSRoman Divacky // If the inserted and extracted elements are constants, they must not 205f22ef01cSRoman Divacky // be the same value, extract from the pre-inserted value instead. 206f22ef01cSRoman Divacky if (isa<Constant>(IE->getOperand(2)) && isa<Constant>(EI.getOperand(1))) { 207f22ef01cSRoman Divacky Worklist.AddValue(EI.getOperand(0)); 208f22ef01cSRoman Divacky EI.setOperand(0, IE->getOperand(0)); 209f22ef01cSRoman Divacky return &EI; 210f22ef01cSRoman Divacky } 211f22ef01cSRoman Divacky } else if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I)) { 212f22ef01cSRoman Divacky // If this is extracting an element from a shufflevector, figure out where 213f22ef01cSRoman Divacky // it came from and extract from the appropriate input element instead. 214f22ef01cSRoman Divacky if (ConstantInt *Elt = dyn_cast<ConstantInt>(EI.getOperand(1))) { 2152754fe60SDimitry Andric int SrcIdx = getShuffleMask(SVI)[Elt->getZExtValue()]; 216f22ef01cSRoman Divacky Value *Src; 217f22ef01cSRoman Divacky unsigned LHSWidth = 218f22ef01cSRoman Divacky cast<VectorType>(SVI->getOperand(0)->getType())->getNumElements(); 219f22ef01cSRoman Divacky 2202754fe60SDimitry Andric if (SrcIdx < 0) 2212754fe60SDimitry Andric return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 2222754fe60SDimitry Andric if (SrcIdx < (int)LHSWidth) 223f22ef01cSRoman Divacky Src = SVI->getOperand(0); 2242754fe60SDimitry Andric else { 225f22ef01cSRoman Divacky SrcIdx -= LHSWidth; 226f22ef01cSRoman Divacky Src = SVI->getOperand(1); 227f22ef01cSRoman Divacky } 2282754fe60SDimitry Andric const Type *Int32Ty = Type::getInt32Ty(EI.getContext()); 229f22ef01cSRoman Divacky return ExtractElementInst::Create(Src, 2302754fe60SDimitry Andric ConstantInt::get(Int32Ty, 231f22ef01cSRoman Divacky SrcIdx, false)); 232f22ef01cSRoman Divacky } 233f22ef01cSRoman Divacky } 234f22ef01cSRoman Divacky // FIXME: Canonicalize extractelement(bitcast) -> bitcast(extractelement) 235f22ef01cSRoman Divacky } 236f22ef01cSRoman Divacky return 0; 237f22ef01cSRoman Divacky } 238f22ef01cSRoman Divacky 239f22ef01cSRoman Divacky /// CollectSingleShuffleElements - If V is a shuffle of values that ONLY returns 240f22ef01cSRoman Divacky /// elements from either LHS or RHS, return the shuffle mask and true. 241f22ef01cSRoman Divacky /// Otherwise, return false. 242f22ef01cSRoman Divacky static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS, 243f22ef01cSRoman Divacky std::vector<Constant*> &Mask) { 244f22ef01cSRoman Divacky assert(V->getType() == LHS->getType() && V->getType() == RHS->getType() && 245f22ef01cSRoman Divacky "Invalid CollectSingleShuffleElements"); 246f22ef01cSRoman Divacky unsigned NumElts = cast<VectorType>(V->getType())->getNumElements(); 247f22ef01cSRoman Divacky 248f22ef01cSRoman Divacky if (isa<UndefValue>(V)) { 249f22ef01cSRoman Divacky Mask.assign(NumElts, UndefValue::get(Type::getInt32Ty(V->getContext()))); 250f22ef01cSRoman Divacky return true; 251f22ef01cSRoman Divacky } 252f22ef01cSRoman Divacky 253f22ef01cSRoman Divacky if (V == LHS) { 254f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) 255f22ef01cSRoman Divacky Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), i)); 256f22ef01cSRoman Divacky return true; 257f22ef01cSRoman Divacky } 258f22ef01cSRoman Divacky 259f22ef01cSRoman Divacky if (V == RHS) { 260f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) 261f22ef01cSRoman Divacky Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), 262f22ef01cSRoman Divacky i+NumElts)); 263f22ef01cSRoman Divacky return true; 264f22ef01cSRoman Divacky } 265f22ef01cSRoman Divacky 266f22ef01cSRoman Divacky if (InsertElementInst *IEI = dyn_cast<InsertElementInst>(V)) { 267f22ef01cSRoman Divacky // If this is an insert of an extract from some other vector, include it. 268f22ef01cSRoman Divacky Value *VecOp = IEI->getOperand(0); 269f22ef01cSRoman Divacky Value *ScalarOp = IEI->getOperand(1); 270f22ef01cSRoman Divacky Value *IdxOp = IEI->getOperand(2); 271f22ef01cSRoman Divacky 272f22ef01cSRoman Divacky if (!isa<ConstantInt>(IdxOp)) 273f22ef01cSRoman Divacky return false; 274f22ef01cSRoman Divacky unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 275f22ef01cSRoman Divacky 276f22ef01cSRoman Divacky if (isa<UndefValue>(ScalarOp)) { // inserting undef into vector. 277f22ef01cSRoman Divacky // Okay, we can handle this if the vector we are insertinting into is 278f22ef01cSRoman Divacky // transitively ok. 279f22ef01cSRoman Divacky if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) { 280f22ef01cSRoman Divacky // If so, update the mask to reflect the inserted undef. 281f22ef01cSRoman Divacky Mask[InsertedIdx] = UndefValue::get(Type::getInt32Ty(V->getContext())); 282f22ef01cSRoman Divacky return true; 283f22ef01cSRoman Divacky } 284f22ef01cSRoman Divacky } else if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)){ 285f22ef01cSRoman Divacky if (isa<ConstantInt>(EI->getOperand(1)) && 286f22ef01cSRoman Divacky EI->getOperand(0)->getType() == V->getType()) { 287f22ef01cSRoman Divacky unsigned ExtractedIdx = 288f22ef01cSRoman Divacky cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 289f22ef01cSRoman Divacky 290f22ef01cSRoman Divacky // This must be extracting from either LHS or RHS. 291f22ef01cSRoman Divacky if (EI->getOperand(0) == LHS || EI->getOperand(0) == RHS) { 292f22ef01cSRoman Divacky // Okay, we can handle this if the vector we are insertinting into is 293f22ef01cSRoman Divacky // transitively ok. 294f22ef01cSRoman Divacky if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) { 295f22ef01cSRoman Divacky // If so, update the mask to reflect the inserted value. 296f22ef01cSRoman Divacky if (EI->getOperand(0) == LHS) { 297f22ef01cSRoman Divacky Mask[InsertedIdx % NumElts] = 298f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(V->getContext()), 299f22ef01cSRoman Divacky ExtractedIdx); 300f22ef01cSRoman Divacky } else { 301f22ef01cSRoman Divacky assert(EI->getOperand(0) == RHS); 302f22ef01cSRoman Divacky Mask[InsertedIdx % NumElts] = 303f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(V->getContext()), 304f22ef01cSRoman Divacky ExtractedIdx+NumElts); 305f22ef01cSRoman Divacky } 306f22ef01cSRoman Divacky return true; 307f22ef01cSRoman Divacky } 308f22ef01cSRoman Divacky } 309f22ef01cSRoman Divacky } 310f22ef01cSRoman Divacky } 311f22ef01cSRoman Divacky } 312f22ef01cSRoman Divacky // TODO: Handle shufflevector here! 313f22ef01cSRoman Divacky 314f22ef01cSRoman Divacky return false; 315f22ef01cSRoman Divacky } 316f22ef01cSRoman Divacky 317f22ef01cSRoman Divacky /// CollectShuffleElements - We are building a shuffle of V, using RHS as the 318f22ef01cSRoman Divacky /// RHS of the shuffle instruction, if it is not null. Return a shuffle mask 319f22ef01cSRoman Divacky /// that computes V and the LHS value of the shuffle. 320f22ef01cSRoman Divacky static Value *CollectShuffleElements(Value *V, std::vector<Constant*> &Mask, 321f22ef01cSRoman Divacky Value *&RHS) { 322f22ef01cSRoman Divacky assert(V->getType()->isVectorTy() && 323f22ef01cSRoman Divacky (RHS == 0 || V->getType() == RHS->getType()) && 324f22ef01cSRoman Divacky "Invalid shuffle!"); 325f22ef01cSRoman Divacky unsigned NumElts = cast<VectorType>(V->getType())->getNumElements(); 326f22ef01cSRoman Divacky 327f22ef01cSRoman Divacky if (isa<UndefValue>(V)) { 328f22ef01cSRoman Divacky Mask.assign(NumElts, UndefValue::get(Type::getInt32Ty(V->getContext()))); 329f22ef01cSRoman Divacky return V; 330f22ef01cSRoman Divacky } else if (isa<ConstantAggregateZero>(V)) { 331f22ef01cSRoman Divacky Mask.assign(NumElts, ConstantInt::get(Type::getInt32Ty(V->getContext()),0)); 332f22ef01cSRoman Divacky return V; 333f22ef01cSRoman Divacky } else if (InsertElementInst *IEI = dyn_cast<InsertElementInst>(V)) { 334f22ef01cSRoman Divacky // If this is an insert of an extract from some other vector, include it. 335f22ef01cSRoman Divacky Value *VecOp = IEI->getOperand(0); 336f22ef01cSRoman Divacky Value *ScalarOp = IEI->getOperand(1); 337f22ef01cSRoman Divacky Value *IdxOp = IEI->getOperand(2); 338f22ef01cSRoman Divacky 339f22ef01cSRoman Divacky if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) { 340f22ef01cSRoman Divacky if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) && 341f22ef01cSRoman Divacky EI->getOperand(0)->getType() == V->getType()) { 342f22ef01cSRoman Divacky unsigned ExtractedIdx = 343f22ef01cSRoman Divacky cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 344f22ef01cSRoman Divacky unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 345f22ef01cSRoman Divacky 346f22ef01cSRoman Divacky // Either the extracted from or inserted into vector must be RHSVec, 347f22ef01cSRoman Divacky // otherwise we'd end up with a shuffle of three inputs. 348f22ef01cSRoman Divacky if (EI->getOperand(0) == RHS || RHS == 0) { 349f22ef01cSRoman Divacky RHS = EI->getOperand(0); 350f22ef01cSRoman Divacky Value *V = CollectShuffleElements(VecOp, Mask, RHS); 351f22ef01cSRoman Divacky Mask[InsertedIdx % NumElts] = 352f22ef01cSRoman Divacky ConstantInt::get(Type::getInt32Ty(V->getContext()), 353f22ef01cSRoman Divacky NumElts+ExtractedIdx); 354f22ef01cSRoman Divacky return V; 355f22ef01cSRoman Divacky } 356f22ef01cSRoman Divacky 357f22ef01cSRoman Divacky if (VecOp == RHS) { 358f22ef01cSRoman Divacky Value *V = CollectShuffleElements(EI->getOperand(0), Mask, RHS); 359f22ef01cSRoman Divacky // Everything but the extracted element is replaced with the RHS. 360f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) { 361f22ef01cSRoman Divacky if (i != InsertedIdx) 362f22ef01cSRoman Divacky Mask[i] = ConstantInt::get(Type::getInt32Ty(V->getContext()), 363f22ef01cSRoman Divacky NumElts+i); 364f22ef01cSRoman Divacky } 365f22ef01cSRoman Divacky return V; 366f22ef01cSRoman Divacky } 367f22ef01cSRoman Divacky 368f22ef01cSRoman Divacky // If this insertelement is a chain that comes from exactly these two 369f22ef01cSRoman Divacky // vectors, return the vector and the effective shuffle. 370f22ef01cSRoman Divacky if (CollectSingleShuffleElements(IEI, EI->getOperand(0), RHS, Mask)) 371f22ef01cSRoman Divacky return EI->getOperand(0); 372f22ef01cSRoman Divacky } 373f22ef01cSRoman Divacky } 374f22ef01cSRoman Divacky } 375f22ef01cSRoman Divacky // TODO: Handle shufflevector here! 376f22ef01cSRoman Divacky 377f22ef01cSRoman Divacky // Otherwise, can't do anything fancy. Return an identity vector. 378f22ef01cSRoman Divacky for (unsigned i = 0; i != NumElts; ++i) 379f22ef01cSRoman Divacky Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), i)); 380f22ef01cSRoman Divacky return V; 381f22ef01cSRoman Divacky } 382f22ef01cSRoman Divacky 383f22ef01cSRoman Divacky Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { 384f22ef01cSRoman Divacky Value *VecOp = IE.getOperand(0); 385f22ef01cSRoman Divacky Value *ScalarOp = IE.getOperand(1); 386f22ef01cSRoman Divacky Value *IdxOp = IE.getOperand(2); 387f22ef01cSRoman Divacky 388f22ef01cSRoman Divacky // Inserting an undef or into an undefined place, remove this. 389f22ef01cSRoman Divacky if (isa<UndefValue>(ScalarOp) || isa<UndefValue>(IdxOp)) 390f22ef01cSRoman Divacky ReplaceInstUsesWith(IE, VecOp); 391f22ef01cSRoman Divacky 392f22ef01cSRoman Divacky // If the inserted element was extracted from some other vector, and if the 393f22ef01cSRoman Divacky // indexes are constant, try to turn this into a shufflevector operation. 394f22ef01cSRoman Divacky if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) { 395f22ef01cSRoman Divacky if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) && 396f22ef01cSRoman Divacky EI->getOperand(0)->getType() == IE.getType()) { 397f22ef01cSRoman Divacky unsigned NumVectorElts = IE.getType()->getNumElements(); 398f22ef01cSRoman Divacky unsigned ExtractedIdx = 399f22ef01cSRoman Divacky cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 400f22ef01cSRoman Divacky unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 401f22ef01cSRoman Divacky 402f22ef01cSRoman Divacky if (ExtractedIdx >= NumVectorElts) // Out of range extract. 403f22ef01cSRoman Divacky return ReplaceInstUsesWith(IE, VecOp); 404f22ef01cSRoman Divacky 405f22ef01cSRoman Divacky if (InsertedIdx >= NumVectorElts) // Out of range insert. 406f22ef01cSRoman Divacky return ReplaceInstUsesWith(IE, UndefValue::get(IE.getType())); 407f22ef01cSRoman Divacky 408f22ef01cSRoman Divacky // If we are extracting a value from a vector, then inserting it right 409f22ef01cSRoman Divacky // back into the same place, just use the input vector. 410f22ef01cSRoman Divacky if (EI->getOperand(0) == VecOp && ExtractedIdx == InsertedIdx) 411f22ef01cSRoman Divacky return ReplaceInstUsesWith(IE, VecOp); 412f22ef01cSRoman Divacky 413f22ef01cSRoman Divacky // If this insertelement isn't used by some other insertelement, turn it 414f22ef01cSRoman Divacky // (and any insertelements it points to), into one big shuffle. 415f22ef01cSRoman Divacky if (!IE.hasOneUse() || !isa<InsertElementInst>(IE.use_back())) { 416f22ef01cSRoman Divacky std::vector<Constant*> Mask; 417f22ef01cSRoman Divacky Value *RHS = 0; 418f22ef01cSRoman Divacky Value *LHS = CollectShuffleElements(&IE, Mask, RHS); 419f22ef01cSRoman Divacky if (RHS == 0) RHS = UndefValue::get(LHS->getType()); 420f22ef01cSRoman Divacky // We now have a shuffle of LHS, RHS, Mask. 4212754fe60SDimitry Andric return new ShuffleVectorInst(LHS, RHS, ConstantVector::get(Mask)); 422f22ef01cSRoman Divacky } 423f22ef01cSRoman Divacky } 424f22ef01cSRoman Divacky } 425f22ef01cSRoman Divacky 426f22ef01cSRoman Divacky unsigned VWidth = cast<VectorType>(VecOp->getType())->getNumElements(); 427f22ef01cSRoman Divacky APInt UndefElts(VWidth, 0); 428f22ef01cSRoman Divacky APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); 4292754fe60SDimitry Andric if (Value *V = SimplifyDemandedVectorElts(&IE, AllOnesEltMask, UndefElts)) { 4302754fe60SDimitry Andric if (V != &IE) 4312754fe60SDimitry Andric return ReplaceInstUsesWith(IE, V); 432f22ef01cSRoman Divacky return &IE; 4332754fe60SDimitry Andric } 434f22ef01cSRoman Divacky 435f22ef01cSRoman Divacky return 0; 436f22ef01cSRoman Divacky } 437f22ef01cSRoman Divacky 438f22ef01cSRoman Divacky 439f22ef01cSRoman Divacky Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { 440f22ef01cSRoman Divacky Value *LHS = SVI.getOperand(0); 441f22ef01cSRoman Divacky Value *RHS = SVI.getOperand(1); 4422754fe60SDimitry Andric std::vector<int> Mask = getShuffleMask(&SVI); 443f22ef01cSRoman Divacky 444f22ef01cSRoman Divacky bool MadeChange = false; 445f22ef01cSRoman Divacky 446f22ef01cSRoman Divacky // Undefined shuffle mask -> undefined value. 447f22ef01cSRoman Divacky if (isa<UndefValue>(SVI.getOperand(2))) 448f22ef01cSRoman Divacky return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType())); 449f22ef01cSRoman Divacky 450f22ef01cSRoman Divacky unsigned VWidth = cast<VectorType>(SVI.getType())->getNumElements(); 451f22ef01cSRoman Divacky 452f22ef01cSRoman Divacky if (VWidth != cast<VectorType>(LHS->getType())->getNumElements()) 453f22ef01cSRoman Divacky return 0; 454f22ef01cSRoman Divacky 455f22ef01cSRoman Divacky APInt UndefElts(VWidth, 0); 456f22ef01cSRoman Divacky APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); 4572754fe60SDimitry Andric if (Value *V = SimplifyDemandedVectorElts(&SVI, AllOnesEltMask, UndefElts)) { 4582754fe60SDimitry Andric if (V != &SVI) 4592754fe60SDimitry Andric return ReplaceInstUsesWith(SVI, V); 460f22ef01cSRoman Divacky LHS = SVI.getOperand(0); 461f22ef01cSRoman Divacky RHS = SVI.getOperand(1); 462f22ef01cSRoman Divacky MadeChange = true; 463f22ef01cSRoman Divacky } 464f22ef01cSRoman Divacky 465f22ef01cSRoman Divacky // Canonicalize shuffle(x ,x,mask) -> shuffle(x, undef,mask') 466f22ef01cSRoman Divacky // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask'). 467f22ef01cSRoman Divacky if (LHS == RHS || isa<UndefValue>(LHS)) { 468f22ef01cSRoman Divacky if (isa<UndefValue>(LHS) && LHS == RHS) { 469f22ef01cSRoman Divacky // shuffle(undef,undef,mask) -> undef. 470f22ef01cSRoman Divacky return ReplaceInstUsesWith(SVI, LHS); 471f22ef01cSRoman Divacky } 472f22ef01cSRoman Divacky 473f22ef01cSRoman Divacky // Remap any references to RHS to use LHS. 474f22ef01cSRoman Divacky std::vector<Constant*> Elts; 475f22ef01cSRoman Divacky for (unsigned i = 0, e = Mask.size(); i != e; ++i) { 4762754fe60SDimitry Andric if (Mask[i] < 0) 477f22ef01cSRoman Divacky Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); 478f22ef01cSRoman Divacky else { 4792754fe60SDimitry Andric if ((Mask[i] >= (int)e && isa<UndefValue>(RHS)) || 4802754fe60SDimitry Andric (Mask[i] < (int)e && isa<UndefValue>(LHS))) { 4812754fe60SDimitry Andric Mask[i] = -1; // Turn into undef. 482f22ef01cSRoman Divacky Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); 483f22ef01cSRoman Divacky } else { 484f22ef01cSRoman Divacky Mask[i] = Mask[i] % e; // Force to LHS. 485f22ef01cSRoman Divacky Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()), 486f22ef01cSRoman Divacky Mask[i])); 487f22ef01cSRoman Divacky } 488f22ef01cSRoman Divacky } 489f22ef01cSRoman Divacky } 490f22ef01cSRoman Divacky SVI.setOperand(0, SVI.getOperand(1)); 491f22ef01cSRoman Divacky SVI.setOperand(1, UndefValue::get(RHS->getType())); 492f22ef01cSRoman Divacky SVI.setOperand(2, ConstantVector::get(Elts)); 493f22ef01cSRoman Divacky LHS = SVI.getOperand(0); 494f22ef01cSRoman Divacky RHS = SVI.getOperand(1); 495f22ef01cSRoman Divacky MadeChange = true; 496f22ef01cSRoman Divacky } 497f22ef01cSRoman Divacky 498f22ef01cSRoman Divacky // Analyze the shuffle, are the LHS or RHS and identity shuffles? 499f22ef01cSRoman Divacky bool isLHSID = true, isRHSID = true; 500f22ef01cSRoman Divacky 501f22ef01cSRoman Divacky for (unsigned i = 0, e = Mask.size(); i != e; ++i) { 5022754fe60SDimitry Andric if (Mask[i] < 0) continue; // Ignore undef values. 503f22ef01cSRoman Divacky // Is this an identity shuffle of the LHS value? 5042754fe60SDimitry Andric isLHSID &= (Mask[i] == (int)i); 505f22ef01cSRoman Divacky 506f22ef01cSRoman Divacky // Is this an identity shuffle of the RHS value? 507f22ef01cSRoman Divacky isRHSID &= (Mask[i]-e == i); 508f22ef01cSRoman Divacky } 509f22ef01cSRoman Divacky 510f22ef01cSRoman Divacky // Eliminate identity shuffles. 511f22ef01cSRoman Divacky if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); 512f22ef01cSRoman Divacky if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); 513f22ef01cSRoman Divacky 514f22ef01cSRoman Divacky // If the LHS is a shufflevector itself, see if we can combine it with this 515f22ef01cSRoman Divacky // one without producing an unusual shuffle. Here we are really conservative: 516f22ef01cSRoman Divacky // we are absolutely afraid of producing a shuffle mask not in the input 517f22ef01cSRoman Divacky // program, because the code gen may not be smart enough to turn a merged 518f22ef01cSRoman Divacky // shuffle into two specific shuffles: it may produce worse code. As such, 5192754fe60SDimitry Andric // we only merge two shuffles if the result is either a splat or one of the 5202754fe60SDimitry Andric // two input shuffle masks. In this case, merging the shuffles just removes 5212754fe60SDimitry Andric // one instruction, which we know is safe. This is good for things like 5222754fe60SDimitry Andric // turning: (splat(splat)) -> splat. 523f22ef01cSRoman Divacky if (ShuffleVectorInst *LHSSVI = dyn_cast<ShuffleVectorInst>(LHS)) { 524f22ef01cSRoman Divacky if (isa<UndefValue>(RHS)) { 5252754fe60SDimitry Andric std::vector<int> LHSMask = getShuffleMask(LHSSVI); 526f22ef01cSRoman Divacky 527f22ef01cSRoman Divacky if (LHSMask.size() == Mask.size()) { 5282754fe60SDimitry Andric std::vector<int> NewMask; 5292754fe60SDimitry Andric bool isSplat = true; 5302754fe60SDimitry Andric int SplatElt = -1; // undef 5312754fe60SDimitry Andric for (unsigned i = 0, e = Mask.size(); i != e; ++i) { 5322754fe60SDimitry Andric int MaskElt; 5332754fe60SDimitry Andric if (Mask[i] < 0 || Mask[i] >= (int)e) 5342754fe60SDimitry Andric MaskElt = -1; // undef 535f22ef01cSRoman Divacky else 5362754fe60SDimitry Andric MaskElt = LHSMask[Mask[i]]; 5372754fe60SDimitry Andric // Check if this could still be a splat. 5382754fe60SDimitry Andric if (MaskElt >= 0) { 5392754fe60SDimitry Andric if (SplatElt >=0 && SplatElt != MaskElt) 5402754fe60SDimitry Andric isSplat = false; 5412754fe60SDimitry Andric SplatElt = MaskElt; 5422754fe60SDimitry Andric } 5432754fe60SDimitry Andric NewMask.push_back(MaskElt); 5442754fe60SDimitry Andric } 545f22ef01cSRoman Divacky 546f22ef01cSRoman Divacky // If the result mask is equal to the src shuffle or this 547f22ef01cSRoman Divacky // shuffle mask, do the replacement. 5482754fe60SDimitry Andric if (isSplat || NewMask == LHSMask || NewMask == Mask) { 549f22ef01cSRoman Divacky std::vector<Constant*> Elts; 5502754fe60SDimitry Andric const Type *Int32Ty = Type::getInt32Ty(SVI.getContext()); 551f22ef01cSRoman Divacky for (unsigned i = 0, e = NewMask.size(); i != e; ++i) { 5522754fe60SDimitry Andric if (NewMask[i] < 0) { 5532754fe60SDimitry Andric Elts.push_back(UndefValue::get(Int32Ty)); 554f22ef01cSRoman Divacky } else { 5552754fe60SDimitry Andric Elts.push_back(ConstantInt::get(Int32Ty, NewMask[i])); 556f22ef01cSRoman Divacky } 557f22ef01cSRoman Divacky } 558f22ef01cSRoman Divacky return new ShuffleVectorInst(LHSSVI->getOperand(0), 559f22ef01cSRoman Divacky LHSSVI->getOperand(1), 560f22ef01cSRoman Divacky ConstantVector::get(Elts)); 561f22ef01cSRoman Divacky } 562f22ef01cSRoman Divacky } 563f22ef01cSRoman Divacky } 564f22ef01cSRoman Divacky } 565f22ef01cSRoman Divacky 566f22ef01cSRoman Divacky return MadeChange ? &SVI : 0; 567f22ef01cSRoman Divacky } 568