1b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner//===- InstCombineVectorOps.cpp -------------------------------------------===// 2b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// 3b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// The LLVM Compiler Infrastructure 4b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// 5b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// This file is distributed under the University of Illinois Open Source 6b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// License. See LICENSE.TXT for details. 7b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// 8b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner//===----------------------------------------------------------------------===// 9b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// 10b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// This file implements instcombine for ExtractElement, InsertElement and 11b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// ShuffleVector. 12b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner// 13b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner//===----------------------------------------------------------------------===// 14b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 15b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner#include "InstCombine.h" 1683d585383345b84ae4a9590e97135f95ae39406bNadav Rotem#include "llvm/Support/PatternMatch.h" 17b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattnerusing namespace llvm; 1883d585383345b84ae4a9590e97135f95ae39406bNadav Rotemusing namespace PatternMatch; 19b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 20b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// CheapToScalarize - Return true if the value is cheaper to scalarize than it 21bec2d03c4d774e67ebc586b3a00792d996f26140Chris Lattner/// is to leave as a vector operation. isConstant indicates whether we're 22bec2d03c4d774e67ebc586b3a00792d996f26140Chris Lattner/// extracting one known element. If false we're extracting a variable index. 23b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattnerstatic bool CheapToScalarize(Value *V, bool isConstant) { 24230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (Constant *C = dyn_cast<Constant>(V)) { 25b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isConstant) return true; 26230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner 27230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner // If all elts are the same, we can extract it and use any of the values. 28230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner Constant *Op0 = C->getAggregateElement(0U); 29230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner for (unsigned i = 1, e = V->getType()->getVectorNumElements(); i != e; ++i) 30230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (C->getAggregateElement(i) != Op0) 31b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return false; 32b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 33b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 34b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Instruction *I = dyn_cast<Instruction>(V); 35b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (!I) return false; 3609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 37b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Insert element gets simplified to the inserted element or is deleted if 38b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // this is constant idx extract element and its a constant idx insertelt. 39b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (I->getOpcode() == Instruction::InsertElement && isConstant && 40b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner isa<ConstantInt>(I->getOperand(2))) 41b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 42b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (I->getOpcode() == Instruction::Load && I->hasOneUse()) 43b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 44b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) 45b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (BO->hasOneUse() && 46b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner (CheapToScalarize(BO->getOperand(0), isConstant) || 47b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner CheapToScalarize(BO->getOperand(1), isConstant))) 48b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 49b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (CmpInst *CI = dyn_cast<CmpInst>(I)) 50b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (CI->hasOneUse() && 51b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner (CheapToScalarize(CI->getOperand(0), isConstant) || 52b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner CheapToScalarize(CI->getOperand(1), isConstant))) 53b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 5409fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 55b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return false; 56b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 57b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 58b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// FindScalarElement - Given a vector and an element number, see if the scalar 59b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// value is already around as a register, for example if it were inserted then 60b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// extracted from the vector. 61b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattnerstatic Value *FindScalarElement(Value *V, unsigned EltNo) { 621df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands assert(V->getType()->isVectorTy() && "Not looking at a vector?"); 63230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner VectorType *VTy = cast<VectorType>(V->getType()); 64230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner unsigned Width = VTy->getNumElements(); 65b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (EltNo >= Width) // Out of range access. 66230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner return UndefValue::get(VTy->getElementType()); 6709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 68230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (Constant *C = dyn_cast<Constant>(V)) 69230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner return C->getAggregateElement(EltNo); 7009fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 71d5da27186350345794b82f036d75f6d1e9bfbbbdChris Lattner if (InsertElementInst *III = dyn_cast<InsertElementInst>(V)) { 72b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this is an insert to a variable element, we don't know what it is. 7309fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson if (!isa<ConstantInt>(III->getOperand(2))) 74b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return 0; 75b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned IIElt = cast<ConstantInt>(III->getOperand(2))->getZExtValue(); 7609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 77b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this is an insert to the element we are looking for, return the 78b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // inserted value. 7909fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson if (EltNo == IIElt) 80b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return III->getOperand(1); 8109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 82b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Otherwise, the insertelement doesn't modify the value, recurse on its 83b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // vector input. 84b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return FindScalarElement(III->getOperand(0), EltNo); 85d5da27186350345794b82f036d75f6d1e9bfbbbdChris Lattner } 8609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 87d5da27186350345794b82f036d75f6d1e9bfbbbdChris Lattner if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(V)) { 88230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner unsigned LHSWidth = SVI->getOperand(0)->getType()->getVectorNumElements(); 898d992f5c2c90ebc8963679de51f461dc5d54fae1Eli Friedman int InEl = SVI->getMaskValue(EltNo); 9009fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson if (InEl < 0) 91230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner return UndefValue::get(VTy->getElementType()); 92822cb58d087ab67804037807e130273481b86137Bob Wilson if (InEl < (int)LHSWidth) 93822cb58d087ab67804037807e130273481b86137Bob Wilson return FindScalarElement(SVI->getOperand(0), InEl); 94822cb58d087ab67804037807e130273481b86137Bob Wilson return FindScalarElement(SVI->getOperand(1), InEl - LHSWidth); 95b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 9609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 9783d585383345b84ae4a9590e97135f95ae39406bNadav Rotem // Extract a value from a vector add operation with a constant zero. 9883d585383345b84ae4a9590e97135f95ae39406bNadav Rotem Value *Val = 0; Constant *Con = 0; 9983d585383345b84ae4a9590e97135f95ae39406bNadav Rotem if (match(V, m_Add(m_Value(Val), m_Constant(Con)))) { 10083d585383345b84ae4a9590e97135f95ae39406bNadav Rotem if (Con->getAggregateElement(EltNo)->isNullValue()) 10183d585383345b84ae4a9590e97135f95ae39406bNadav Rotem return FindScalarElement(Val, EltNo); 10283d585383345b84ae4a9590e97135f95ae39406bNadav Rotem } 10383d585383345b84ae4a9590e97135f95ae39406bNadav Rotem 104b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Otherwise, we don't know. 105b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return 0; 106b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 107b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 108b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris LattnerInstruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { 109230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner // If vector val is constant with all elements the same, replace EI with 110230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner // that element. We handle a known element # below. 111230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (Constant *C = dyn_cast<Constant>(EI.getOperand(0))) 112230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (CheapToScalarize(C, false)) 113230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner return ReplaceInstUsesWith(EI, C->getAggregateElement(0U)); 11409fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 115b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If extracting a specified index from the vector, see if we can recursively 116b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // find a previously computed scalar that was inserted into the vector. 117b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (ConstantInt *IdxC = dyn_cast<ConstantInt>(EI.getOperand(1))) { 118b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned IndexVal = IdxC->getZExtValue(); 119b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned VectorWidth = EI.getVectorOperandType()->getNumElements(); 12009fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 121b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this is extracting an invalid index, turn this into undef, to avoid 122b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // crashing the code below. 123b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (IndexVal >= VectorWidth) 124b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 12509fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 126b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // This instruction only demands the single element from the input vector. 127b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If the input vector has a single use, simplify it based on this use 128b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // property. 129b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (EI.getOperand(0)->hasOneUse() && VectorWidth != 1) { 130b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner APInt UndefElts(VectorWidth, 0); 1318609fda0f7e4446de85f882755601ffcbd540324Chris Lattner APInt DemandedMask(VectorWidth, 0); 1327a874ddda037349184fbeb22838cc11a1a9bb78fJay Foad DemandedMask.setBit(IndexVal); 133b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (Value *V = SimplifyDemandedVectorElts(EI.getOperand(0), 134b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner DemandedMask, UndefElts)) { 135b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner EI.setOperand(0, V); 136b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return &EI; 137b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 138b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 13909fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 140b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (Value *Elt = FindScalarElement(EI.getOperand(0), IndexVal)) 141b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ReplaceInstUsesWith(EI, Elt); 14209fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 143b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If the this extractelement is directly using a bitcast from a vector of 144b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // the same number of elements, see if we can find the source element from 145b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // it. In this case, we will end up needing to bitcast the scalars. 146b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (BitCastInst *BCI = dyn_cast<BitCastInst>(EI.getOperand(0))) { 147230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (VectorType *VT = dyn_cast<VectorType>(BCI->getOperand(0)->getType())) 148b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (VT->getNumElements() == VectorWidth) 149b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (Value *Elt = FindScalarElement(BCI->getOperand(0), IndexVal)) 150b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return new BitCastInst(Elt, EI.getType()); 151b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 152b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 15309fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 154b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0))) { 155b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Push extractelement into predecessor operation if legal and 156b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // profitable to do so 157b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 158b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (I->hasOneUse() && 159b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner CheapToScalarize(BO, isa<ConstantInt>(EI.getOperand(1)))) { 160b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *newEI0 = 161db1da8ed42cbe50945acfaca514864723999150aBob Wilson Builder->CreateExtractElement(BO->getOperand(0), EI.getOperand(1), 162db1da8ed42cbe50945acfaca514864723999150aBob Wilson EI.getName()+".lhs"); 163b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *newEI1 = 164db1da8ed42cbe50945acfaca514864723999150aBob Wilson Builder->CreateExtractElement(BO->getOperand(1), EI.getOperand(1), 165db1da8ed42cbe50945acfaca514864723999150aBob Wilson EI.getName()+".rhs"); 166b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1); 167b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 168b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } else if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) { 169b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Extracting the inserted element? 170b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (IE->getOperand(2) == EI.getOperand(1)) 171b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ReplaceInstUsesWith(EI, IE->getOperand(1)); 172b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If the inserted and extracted elements are constants, they must not 173b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // be the same value, extract from the pre-inserted value instead. 174b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<Constant>(IE->getOperand(2)) && isa<Constant>(EI.getOperand(1))) { 175b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Worklist.AddValue(EI.getOperand(0)); 176b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner EI.setOperand(0, IE->getOperand(0)); 177b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return &EI; 178b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 179b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } else if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I)) { 180b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this is extracting an element from a shufflevector, figure out where 181b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // it came from and extract from the appropriate input element instead. 182b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (ConstantInt *Elt = dyn_cast<ConstantInt>(EI.getOperand(1))) { 1838d992f5c2c90ebc8963679de51f461dc5d54fae1Eli Friedman int SrcIdx = SVI->getMaskValue(Elt->getZExtValue()); 184b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *Src; 185b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned LHSWidth = 186230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner SVI->getOperand(0)->getType()->getVectorNumElements(); 18709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 188822cb58d087ab67804037807e130273481b86137Bob Wilson if (SrcIdx < 0) 189822cb58d087ab67804037807e130273481b86137Bob Wilson return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); 190822cb58d087ab67804037807e130273481b86137Bob Wilson if (SrcIdx < (int)LHSWidth) 191b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Src = SVI->getOperand(0); 192822cb58d087ab67804037807e130273481b86137Bob Wilson else { 193b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner SrcIdx -= LHSWidth; 194b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Src = SVI->getOperand(1); 195b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 196db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Int32Ty = Type::getInt32Ty(EI.getContext()); 197b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ExtractElementInst::Create(Src, 198f0b48f836e85e4e9ae3b5f94c47500d40e3dc16eBob Wilson ConstantInt::get(Int32Ty, 199b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner SrcIdx, false)); 200b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 2010ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem } else if (CastInst *CI = dyn_cast<CastInst>(I)) { 2020ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem // Canonicalize extractelement(cast) -> cast(extractelement) 2030ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem // bitcasts can change the number of vector elements and they cost nothing 2040ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem if (CI->hasOneUse() && EI.hasOneUse() && 2050ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem (CI->getOpcode() != Instruction::BitCast)) { 2060ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem Value *EE = Builder->CreateExtractElement(CI->getOperand(0), 2070ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem EI.getIndexOperand()); 2080ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem return CastInst::Create(CI->getOpcode(), EE, EI.getType()); 2090ff8a4fa35db853dfc3dbe54535aa326d8e742a2Nadav Rotem } 210b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 211b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 212b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return 0; 213b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 214b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 215b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// CollectSingleShuffleElements - If V is a shuffle of values that ONLY returns 21609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson/// elements from either LHS or RHS, return the shuffle mask and true. 217b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// Otherwise, return false. 218b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattnerstatic bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS, 219a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner SmallVectorImpl<Constant*> &Mask) { 220b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner assert(V->getType() == LHS->getType() && V->getType() == RHS->getType() && 221b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner "Invalid CollectSingleShuffleElements"); 222b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned NumElts = cast<VectorType>(V->getType())->getNumElements(); 22309fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 224b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<UndefValue>(V)) { 225b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask.assign(NumElts, UndefValue::get(Type::getInt32Ty(V->getContext()))); 226b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 227b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 22809fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 229b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (V == LHS) { 230b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner for (unsigned i = 0; i != NumElts; ++i) 231b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), i)); 232b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 233b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 23409fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 235b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (V == RHS) { 236b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner for (unsigned i = 0; i != NumElts; ++i) 237b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), 238b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner i+NumElts)); 239b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 240b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 24109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 242b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (InsertElementInst *IEI = dyn_cast<InsertElementInst>(V)) { 243b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this is an insert of an extract from some other vector, include it. 244b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *VecOp = IEI->getOperand(0); 245b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *ScalarOp = IEI->getOperand(1); 246b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *IdxOp = IEI->getOperand(2); 24709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 248b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (!isa<ConstantInt>(IdxOp)) 249b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return false; 250b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 25109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 252b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<UndefValue>(ScalarOp)) { // inserting undef into vector. 253b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Okay, we can handle this if the vector we are insertinting into is 254b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // transitively ok. 255b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) { 256b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If so, update the mask to reflect the inserted undef. 257b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask[InsertedIdx] = UndefValue::get(Type::getInt32Ty(V->getContext())); 258b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 25909fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson } 260b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } else if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)){ 261b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<ConstantInt>(EI->getOperand(1)) && 262b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner EI->getOperand(0)->getType() == V->getType()) { 263b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned ExtractedIdx = 264b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 26509fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 266b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // This must be extracting from either LHS or RHS. 267b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (EI->getOperand(0) == LHS || EI->getOperand(0) == RHS) { 268b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Okay, we can handle this if the vector we are insertinting into is 269b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // transitively ok. 270b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) { 271b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If so, update the mask to reflect the inserted value. 272b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (EI->getOperand(0) == LHS) { 27309fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson Mask[InsertedIdx % NumElts] = 274b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner ConstantInt::get(Type::getInt32Ty(V->getContext()), 275b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner ExtractedIdx); 276b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } else { 277b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner assert(EI->getOperand(0) == RHS); 27809fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson Mask[InsertedIdx % NumElts] = 279b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner ConstantInt::get(Type::getInt32Ty(V->getContext()), 280b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner ExtractedIdx+NumElts); 281b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 282b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return true; 283b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 284b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 285b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 286b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 287b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 288b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // TODO: Handle shufflevector here! 28909fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 290b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return false; 291b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 292b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 293b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// CollectShuffleElements - We are building a shuffle of V, using RHS as the 294b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// RHS of the shuffle instruction, if it is not null. Return a shuffle mask 295b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner/// that computes V and the LHS value of the shuffle. 296a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattnerstatic Value *CollectShuffleElements(Value *V, SmallVectorImpl<Constant*> &Mask, 297b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *&RHS) { 29809fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson assert(V->getType()->isVectorTy() && 299b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner (RHS == 0 || V->getType() == RHS->getType()) && 300b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner "Invalid shuffle!"); 301b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned NumElts = cast<VectorType>(V->getType())->getNumElements(); 30209fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 303b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<UndefValue>(V)) { 304b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask.assign(NumElts, UndefValue::get(Type::getInt32Ty(V->getContext()))); 305b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return V; 306bec2d03c4d774e67ebc586b3a00792d996f26140Chris Lattner } 30737d093f0b0e4b4d1c49efbf2bdcc9827527e3b9fCraig Topper 308bec2d03c4d774e67ebc586b3a00792d996f26140Chris Lattner if (isa<ConstantAggregateZero>(V)) { 309b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask.assign(NumElts, ConstantInt::get(Type::getInt32Ty(V->getContext()),0)); 310b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return V; 311bec2d03c4d774e67ebc586b3a00792d996f26140Chris Lattner } 31237d093f0b0e4b4d1c49efbf2bdcc9827527e3b9fCraig Topper 313bec2d03c4d774e67ebc586b3a00792d996f26140Chris Lattner if (InsertElementInst *IEI = dyn_cast<InsertElementInst>(V)) { 314b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this is an insert of an extract from some other vector, include it. 315b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *VecOp = IEI->getOperand(0); 316b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *ScalarOp = IEI->getOperand(1); 317b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *IdxOp = IEI->getOperand(2); 31809fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 319b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) { 320b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) && 321b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner EI->getOperand(0)->getType() == V->getType()) { 322b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned ExtractedIdx = 323db1da8ed42cbe50945acfaca514864723999150aBob Wilson cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 324b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 32509fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 326b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Either the extracted from or inserted into vector must be RHSVec, 327b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // otherwise we'd end up with a shuffle of three inputs. 328b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (EI->getOperand(0) == RHS || RHS == 0) { 329b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner RHS = EI->getOperand(0); 330b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *V = CollectShuffleElements(VecOp, Mask, RHS); 33109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson Mask[InsertedIdx % NumElts] = 332db1da8ed42cbe50945acfaca514864723999150aBob Wilson ConstantInt::get(Type::getInt32Ty(V->getContext()), 333db1da8ed42cbe50945acfaca514864723999150aBob Wilson NumElts+ExtractedIdx); 334b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return V; 335b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 33609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 337b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (VecOp == RHS) { 338b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *V = CollectShuffleElements(EI->getOperand(0), Mask, RHS); 339b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Everything but the extracted element is replaced with the RHS. 340b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner for (unsigned i = 0; i != NumElts; ++i) { 341b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (i != InsertedIdx) 342b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask[i] = ConstantInt::get(Type::getInt32Ty(V->getContext()), 343b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner NumElts+i); 344b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 345b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return V; 346b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 34709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 348b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this insertelement is a chain that comes from exactly these two 349b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // vectors, return the vector and the effective shuffle. 350b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (CollectSingleShuffleElements(IEI, EI->getOperand(0), RHS, Mask)) 351b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return EI->getOperand(0); 352b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 353b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 354b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 355b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // TODO: Handle shufflevector here! 35609fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 357b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Otherwise, can't do anything fancy. Return an identity vector. 358b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner for (unsigned i = 0; i != NumElts; ++i) 359b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Mask.push_back(ConstantInt::get(Type::getInt32Ty(V->getContext()), i)); 360b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return V; 361b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 362b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 363b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris LattnerInstruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { 364b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *VecOp = IE.getOperand(0); 365b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *ScalarOp = IE.getOperand(1); 366b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *IdxOp = IE.getOperand(2); 36709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 368b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Inserting an undef or into an undefined place, remove this. 369b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<UndefValue>(ScalarOp) || isa<UndefValue>(IdxOp)) 370b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner ReplaceInstUsesWith(IE, VecOp); 37109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 37209fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson // If the inserted element was extracted from some other vector, and if the 373b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // indexes are constant, try to turn this into a shufflevector operation. 374b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) { 375b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) && 376b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner EI->getOperand(0)->getType() == IE.getType()) { 377b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned NumVectorElts = IE.getType()->getNumElements(); 378b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned ExtractedIdx = 379db1da8ed42cbe50945acfaca514864723999150aBob Wilson cast<ConstantInt>(EI->getOperand(1))->getZExtValue(); 380b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue(); 38109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 382b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (ExtractedIdx >= NumVectorElts) // Out of range extract. 383b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ReplaceInstUsesWith(IE, VecOp); 38409fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 385b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (InsertedIdx >= NumVectorElts) // Out of range insert. 386b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ReplaceInstUsesWith(IE, UndefValue::get(IE.getType())); 38709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 388b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If we are extracting a value from a vector, then inserting it right 389b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // back into the same place, just use the input vector. 390b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (EI->getOperand(0) == VecOp && ExtractedIdx == InsertedIdx) 39109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson return ReplaceInstUsesWith(IE, VecOp); 39209fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 393b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // If this insertelement isn't used by some other insertelement, turn it 394b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // (and any insertelements it points to), into one big shuffle. 395b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (!IE.hasOneUse() || !isa<InsertElementInst>(IE.use_back())) { 396a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner SmallVector<Constant*, 16> Mask; 397b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *RHS = 0; 398b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *LHS = CollectShuffleElements(&IE, Mask, RHS); 399b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (RHS == 0) RHS = UndefValue::get(LHS->getType()); 400b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // We now have a shuffle of LHS, RHS, Mask. 401db1da8ed42cbe50945acfaca514864723999150aBob Wilson return new ShuffleVectorInst(LHS, RHS, ConstantVector::get(Mask)); 402b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 403b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 404b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 40509fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 406b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner unsigned VWidth = cast<VectorType>(VecOp->getType())->getNumElements(); 407b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner APInt UndefElts(VWidth, 0); 408b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); 4091347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman if (Value *V = SimplifyDemandedVectorElts(&IE, AllOnesEltMask, UndefElts)) { 4101347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman if (V != &IE) 4111347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman return ReplaceInstUsesWith(IE, V); 412b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return &IE; 4131347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman } 41409fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 415b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return 0; 416b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 417b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 418b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner 419b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris LattnerInstruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { 420b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *LHS = SVI.getOperand(0); 421b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Value *RHS = SVI.getOperand(1); 422230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner SmallVector<int, 16> Mask = SVI.getShuffleMask(); 42309fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 424b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner bool MadeChange = false; 42509fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 426b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Undefined shuffle mask -> undefined value. 427b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (isa<UndefValue>(SVI.getOperand(2))) 428b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType())); 42909fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 43068c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher unsigned VWidth = cast<VectorType>(SVI.getType())->getNumElements(); 43109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 432b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner APInt UndefElts(VWidth, 0); 433b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); 4341347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman if (Value *V = SimplifyDemandedVectorElts(&SVI, AllOnesEltMask, UndefElts)) { 4351347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman if (V != &SVI) 4361347623aaf25b7fe6486479353fc87bd7541a5f7Eli Friedman return ReplaceInstUsesWith(SVI, V); 437b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner LHS = SVI.getOperand(0); 438b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner RHS = SVI.getOperand(1); 439b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner MadeChange = true; 440b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 44109fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 442d2822e7572e75287db66acb14b2d988a80faebddEli Friedman unsigned LHSWidth = cast<VectorType>(LHS->getType())->getNumElements(); 443d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 444b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Canonicalize shuffle(x ,x,mask) -> shuffle(x, undef,mask') 445b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask'). 446b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner if (LHS == RHS || isa<UndefValue>(LHS)) { 44768c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher if (isa<UndefValue>(LHS) && LHS == RHS) { 44868c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher // shuffle(undef,undef,mask) -> undef. 449d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Value* result = (VWidth == LHSWidth) 450d2822e7572e75287db66acb14b2d988a80faebddEli Friedman ? LHS : UndefValue::get(SVI.getType()); 451d2822e7572e75287db66acb14b2d988a80faebddEli Friedman return ReplaceInstUsesWith(SVI, result); 45268c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher } 45309fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 454b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner // Remap any references to RHS to use LHS. 455a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner SmallVector<Constant*, 16> Elts; 456d2822e7572e75287db66acb14b2d988a80faebddEli Friedman for (unsigned i = 0, e = LHSWidth; i != VWidth; ++i) { 457a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner if (Mask[i] < 0) { 458b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); 459a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner continue; 460a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner } 461a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner 462a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner if ((Mask[i] >= (int)e && isa<UndefValue>(RHS)) || 463a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner (Mask[i] < (int)e && isa<UndefValue>(LHS))) { 464a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner Mask[i] = -1; // Turn into undef. 465a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); 466a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner } else { 467a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner Mask[i] = Mask[i] % e; // Force to LHS. 468a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()), 469a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7aChris Lattner Mask[i])); 470b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 471b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 472b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner SVI.setOperand(0, SVI.getOperand(1)); 473b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner SVI.setOperand(1, UndefValue::get(RHS->getType())); 474b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner SVI.setOperand(2, ConstantVector::get(Elts)); 475b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner LHS = SVI.getOperand(0); 476b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner RHS = SVI.getOperand(1); 477b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner MadeChange = true; 478b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner } 47909fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 480d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (VWidth == LHSWidth) { 481d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Analyze the shuffle, are the LHS or RHS and identity shuffles? 482d2822e7572e75287db66acb14b2d988a80faebddEli Friedman bool isLHSID = true, isRHSID = true; 483d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 484d2822e7572e75287db66acb14b2d988a80faebddEli Friedman for (unsigned i = 0, e = Mask.size(); i != e; ++i) { 485d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (Mask[i] < 0) continue; // Ignore undef values. 486d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Is this an identity shuffle of the LHS value? 487d2822e7572e75287db66acb14b2d988a80faebddEli Friedman isLHSID &= (Mask[i] == (int)i); 48809fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 489d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Is this an identity shuffle of the RHS value? 490d2822e7572e75287db66acb14b2d988a80faebddEli Friedman isRHSID &= (Mask[i]-e == i); 491d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 49209fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 493d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Eliminate identity shuffles. 494d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); 495d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); 49695743d8748a85bbb03aff3b3baae728c138acbabNate Begeman } 49709fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 49868c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher // If the LHS is a shufflevector itself, see if we can combine it with this 499d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // one without producing an unusual shuffle. 500d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Cases that might be simplified: 501d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // 1. 502d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x1=shuffle(v1,v2,mask1) 503d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(x1,undef,mask) 504d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ==> 505d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(v1,undef,newMask) 506d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // newMask[i] = (mask[i] < x1.size()) ? mask1[mask[i]] : -1 507d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // 2. 508d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x1=shuffle(v1,undef,mask1) 509d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(x1,x2,mask) 510d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // where v1.size() == mask1.size() 511d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ==> 512d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(v1,x2,newMask) 513d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // newMask[i] = (mask[i] < x1.size()) ? mask1[mask[i]] : mask[i] 514d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // 3. 515d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x2=shuffle(v2,undef,mask2) 516d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(x1,x2,mask) 517d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // where v2.size() == mask2.size() 518d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ==> 519d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(x1,v2,newMask) 520d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // newMask[i] = (mask[i] < x1.size()) 521d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ? mask[i] : mask2[mask[i]-x1.size()]+x1.size() 522d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // 4. 523d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x1=shuffle(v1,undef,mask1) 524d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x2=shuffle(v2,undef,mask2) 525d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(x1,x2,mask) 526d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // where v1.size() == v2.size() 527d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ==> 528d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // x=shuffle(v1,v2,newMask) 529d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // newMask[i] = (mask[i] < x1.size()) 530d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ? mask1[mask[i]] : mask2[mask[i]-x1.size()]+v1.size() 531d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // 532d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Here we are really conservative: 53368c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher // we are absolutely afraid of producing a shuffle mask not in the input 53468c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher // program, because the code gen may not be smart enough to turn a merged 53568c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher // shuffle into two specific shuffles: it may produce worse code. As such, 5364cac5facc3a95a81ffa2c85baae001a7c509146cBob Wilson // we only merge two shuffles if the result is either a splat or one of the 537d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // input shuffle masks. In this case, merging the shuffles just removes 5384cac5facc3a95a81ffa2c85baae001a7c509146cBob Wilson // one instruction, which we know is safe. This is good for things like 539d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // turning: (splat(splat)) -> splat, or 540d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // merge(V[0..n], V[n+1..2n]) -> V[0..2n] 541d2822e7572e75287db66acb14b2d988a80faebddEli Friedman ShuffleVectorInst* LHSShuffle = dyn_cast<ShuffleVectorInst>(LHS); 542d2822e7572e75287db66acb14b2d988a80faebddEli Friedman ShuffleVectorInst* RHSShuffle = dyn_cast<ShuffleVectorInst>(RHS); 543d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (LHSShuffle) 544d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (!isa<UndefValue>(LHSShuffle->getOperand(1)) && !isa<UndefValue>(RHS)) 545d2822e7572e75287db66acb14b2d988a80faebddEli Friedman LHSShuffle = NULL; 546d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (RHSShuffle) 547d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (!isa<UndefValue>(RHSShuffle->getOperand(1))) 548d2822e7572e75287db66acb14b2d988a80faebddEli Friedman RHSShuffle = NULL; 549d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (!LHSShuffle && !RHSShuffle) 550d2822e7572e75287db66acb14b2d988a80faebddEli Friedman return MadeChange ? &SVI : 0; 551d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 552d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Value* LHSOp0 = NULL; 553d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Value* LHSOp1 = NULL; 554d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Value* RHSOp0 = NULL; 555d2822e7572e75287db66acb14b2d988a80faebddEli Friedman unsigned LHSOp0Width = 0; 556d2822e7572e75287db66acb14b2d988a80faebddEli Friedman unsigned RHSOp0Width = 0; 557d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (LHSShuffle) { 558d2822e7572e75287db66acb14b2d988a80faebddEli Friedman LHSOp0 = LHSShuffle->getOperand(0); 559d2822e7572e75287db66acb14b2d988a80faebddEli Friedman LHSOp1 = LHSShuffle->getOperand(1); 560d2822e7572e75287db66acb14b2d988a80faebddEli Friedman LHSOp0Width = cast<VectorType>(LHSOp0->getType())->getNumElements(); 561d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 562d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (RHSShuffle) { 563d2822e7572e75287db66acb14b2d988a80faebddEli Friedman RHSOp0 = RHSShuffle->getOperand(0); 564d2822e7572e75287db66acb14b2d988a80faebddEli Friedman RHSOp0Width = cast<VectorType>(RHSOp0->getType())->getNumElements(); 565d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 566d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Value* newLHS = LHS; 567d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Value* newRHS = RHS; 568d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (LHSShuffle) { 569d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // case 1 57068c23f861694f7b06df2ce39ced01d1d39fc5809Eric Christopher if (isa<UndefValue>(RHS)) { 571d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newLHS = LHSOp0; 572d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newRHS = LHSOp1; 573d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 574d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // case 2 or 4 575d2822e7572e75287db66acb14b2d988a80faebddEli Friedman else if (LHSOp0Width == LHSWidth) { 576d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newLHS = LHSOp0; 577d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 578d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 579d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // case 3 or 4 580d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (RHSShuffle && RHSOp0Width == LHSWidth) { 581d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newRHS = RHSOp0; 582d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 583d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // case 4 584d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (LHSOp0 == RHSOp0) { 585d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newLHS = LHSOp0; 586d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newRHS = NULL; 587d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 58809fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 589d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (newLHS == LHS && newRHS == RHS) 590d2822e7572e75287db66acb14b2d988a80faebddEli Friedman return MadeChange ? &SVI : 0; 591d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 592d2822e7572e75287db66acb14b2d988a80faebddEli Friedman SmallVector<int, 16> LHSMask; 593d2822e7572e75287db66acb14b2d988a80faebddEli Friedman SmallVector<int, 16> RHSMask; 594230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (newLHS != LHS) 595230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner LHSMask = LHSShuffle->getShuffleMask(); 596230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner if (RHSShuffle && newRHS != RHS) 597230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner RHSMask = RHSShuffle->getShuffleMask(); 598230cdab2205d051cc11c565b69ca8c2106904a76Chris Lattner 599d2822e7572e75287db66acb14b2d988a80faebddEli Friedman unsigned newLHSWidth = (newLHS != LHS) ? LHSOp0Width : LHSWidth; 600d2822e7572e75287db66acb14b2d988a80faebddEli Friedman SmallVector<int, 16> newMask; 601d2822e7572e75287db66acb14b2d988a80faebddEli Friedman bool isSplat = true; 602d2822e7572e75287db66acb14b2d988a80faebddEli Friedman int SplatElt = -1; 603d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Create a new mask for the new ShuffleVectorInst so that the new 604d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // ShuffleVectorInst is equivalent to the original one. 605d2822e7572e75287db66acb14b2d988a80faebddEli Friedman for (unsigned i = 0; i < VWidth; ++i) { 606d2822e7572e75287db66acb14b2d988a80faebddEli Friedman int eltMask; 607081c29b25696006bb72a7ac1035e05f8f935513fCraig Topper if (Mask[i] < 0) { 608d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // This element is an undef value. 609d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = -1; 610d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } else if (Mask[i] < (int)LHSWidth) { 611d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // This element is from left hand side vector operand. 61237d093f0b0e4b4d1c49efbf2bdcc9827527e3b9fCraig Topper // 613d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If LHS is going to be replaced (case 1, 2, or 4), calculate the 614d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // new mask value for the element. 615d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (newLHS != LHS) { 616d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = LHSMask[Mask[i]]; 617d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If the value selected is an undef value, explicitly specify it 618d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // with a -1 mask value. 619d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (eltMask >= (int)LHSOp0Width && isa<UndefValue>(LHSOp1)) 620d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = -1; 62137d093f0b0e4b4d1c49efbf2bdcc9827527e3b9fCraig Topper } else 622d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = Mask[i]; 623d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } else { 624d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // This element is from right hand side vector operand 625d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // 626d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If the value selected is an undef value, explicitly specify it 627d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // with a -1 mask value. (case 1) 628d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (isa<UndefValue>(RHS)) 629d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = -1; 630d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If RHS is going to be replaced (case 3 or 4), calculate the 631d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // new mask value for the element. 632d2822e7572e75287db66acb14b2d988a80faebddEli Friedman else if (newRHS != RHS) { 633d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = RHSMask[Mask[i]-LHSWidth]; 634d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If the value selected is an undef value, explicitly specify it 635d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // with a -1 mask value. 636d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (eltMask >= (int)RHSOp0Width) { 637d2822e7572e75287db66acb14b2d988a80faebddEli Friedman assert(isa<UndefValue>(RHSShuffle->getOperand(1)) 638d2822e7572e75287db66acb14b2d988a80faebddEli Friedman && "should have been check above"); 639d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = -1; 6407f1f4089a142e4f0081ac25699bf682a68247a35Nate Begeman } 64137d093f0b0e4b4d1c49efbf2bdcc9827527e3b9fCraig Topper } else 642d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask = Mask[i]-LHSWidth; 643d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 644d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If LHS's width is changed, shift the mask value accordingly. 645d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If newRHS == NULL, i.e. LHSOp0 == RHSOp0, we want to remap any 6464932bbe20c4b96552dcab332503b80ff3b56ad93Michael Gottesman // references from RHSOp0 to LHSOp0, so we don't need to shift the mask. 6474932bbe20c4b96552dcab332503b80ff3b56ad93Michael Gottesman // If newRHS == newLHS, we want to remap any references from newRHS to 6484932bbe20c4b96552dcab332503b80ff3b56ad93Michael Gottesman // newLHS so that we can properly identify splats that may occur due to 6494932bbe20c4b96552dcab332503b80ff3b56ad93Michael Gottesman // obfuscation accross the two vectors. 6504932bbe20c4b96552dcab332503b80ff3b56ad93Michael Gottesman if (eltMask >= 0 && newRHS != NULL && newLHS != newRHS) 651d2822e7572e75287db66acb14b2d988a80faebddEli Friedman eltMask += newLHSWidth; 652d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 653d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 654d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // Check if this could still be a splat. 655d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (eltMask >= 0) { 656d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (SplatElt >= 0 && SplatElt != eltMask) 657d2822e7572e75287db66acb14b2d988a80faebddEli Friedman isSplat = false; 658d2822e7572e75287db66acb14b2d988a80faebddEli Friedman SplatElt = eltMask; 659d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 660d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 661d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newMask.push_back(eltMask); 662d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 663d2822e7572e75287db66acb14b2d988a80faebddEli Friedman 664d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // If the result mask is equal to one of the original shuffle masks, 665d2822e7572e75287db66acb14b2d988a80faebddEli Friedman // or is a splat, do the replacement. 666d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) { 667d2822e7572e75287db66acb14b2d988a80faebddEli Friedman SmallVector<Constant*, 16> Elts; 668d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Type *Int32Ty = Type::getInt32Ty(SVI.getContext()); 669d2822e7572e75287db66acb14b2d988a80faebddEli Friedman for (unsigned i = 0, e = newMask.size(); i != e; ++i) { 670d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (newMask[i] < 0) { 671d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Elts.push_back(UndefValue::get(Int32Ty)); 672d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } else { 673d2822e7572e75287db66acb14b2d988a80faebddEli Friedman Elts.push_back(ConstantInt::get(Int32Ty, newMask[i])); 674d2822e7572e75287db66acb14b2d988a80faebddEli Friedman } 6757f1f4089a142e4f0081ac25699bf682a68247a35Nate Begeman } 676d2822e7572e75287db66acb14b2d988a80faebddEli Friedman if (newRHS == NULL) 677d2822e7572e75287db66acb14b2d988a80faebddEli Friedman newRHS = UndefValue::get(newLHS->getType()); 678d2822e7572e75287db66acb14b2d988a80faebddEli Friedman return new ShuffleVectorInst(newLHS, newRHS, ConstantVector::get(Elts)); 6797f1f4089a142e4f0081ac25699bf682a68247a35Nate Begeman } 68009fd64644d5da2dacc0916790082ac0dd5d9696dBob Wilson 681b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner return MadeChange ? &SVI : 0; 682b8a5cecd6bc74d6c1c256263f857f79f383e53bdChris Lattner} 683