diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/VectorUtils.cpp | 26 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 30 | 
2 files changed, 39 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp index 72140952ecb..92a880c3762 100644 --- a/llvm/lib/Analysis/VectorUtils.cpp +++ b/llvm/lib/Analysis/VectorUtils.cpp @@ -18,6 +18,8 @@  #include "llvm/IR/GetElementPtrTypeIterator.h"  #include "llvm/IR/PatternMatch.h"  #include "llvm/IR/Value.h" +#include "llvm/IR/Constants.h" +  using namespace llvm;  using namespace llvm::PatternMatch; @@ -406,3 +408,27 @@ Value *llvm::findScalarElement(Value *V, unsigned EltNo) {    // Otherwise, we don't know.    return nullptr;  } + +/// \brief Get splat value if the input is a splat vector or return nullptr. +/// The value may be extracted from a splat constants vector or from +/// a sequence of instructions that broadcast a single value into a vector. +llvm::Value *llvm::getSplatValue(Value *V) { +  llvm::ConstantDataVector *CV = dyn_cast<llvm::ConstantDataVector>(V); +  if (CV) +    return CV->getSplatValue(); +  llvm::ShuffleVectorInst *ShuffleInst = dyn_cast<llvm::ShuffleVectorInst>(V); +  if (!ShuffleInst) +    return nullptr; +  // All-zero (our undef) shuffle mask elements. +  for (int i : ShuffleInst->getShuffleMask()) +    if (i != 0 && i != -1) +      return nullptr; +  // The first shuffle source is 'insertelement' with index 0. +  llvm::InsertElementInst *InsertEltInst = +    dyn_cast<llvm::InsertElementInst>(ShuffleInst->getOperand(0)); +  if (!InsertEltInst || !isa<ConstantInt>(InsertEltInst->getOperand(2)) || +      !cast<ConstantInt>(InsertEltInst->getOperand(2))->isNullValue()) +    return nullptr; + +  return InsertEltInst->getOperand(1); +} diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 63328200f8d..c958f7df019 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -22,6 +22,7 @@  #include "llvm/Analysis/ConstantFolding.h"  #include "llvm/Analysis/TargetLibraryInfo.h"  #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Analysis/VectorUtils.h"  #include "llvm/CodeGen/FastISel.h"  #include "llvm/CodeGen/FunctionLoweringInfo.h"  #include "llvm/CodeGen/GCMetadata.h" @@ -3150,37 +3151,32 @@ static bool getUniformBase(Value *& Ptr, SDValue& Base, SDValue& Index,                             SelectionDAGBuilder* SDB) {    assert(Ptr->getType()->isVectorTy() && "Unexpected pointer type"); -  GetElementPtrInst *Gep = dyn_cast<GetElementPtrInst>(Ptr); -  if (!Gep || Gep->getNumOperands() > 2) +  GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr); +  if (!GEP || GEP->getNumOperands() > 2)      return false; -  ShuffleVectorInst *ShuffleInst =  -    dyn_cast<ShuffleVectorInst>(Gep->getPointerOperand()); -  if (!ShuffleInst || !ShuffleInst->getMask()->isNullValue() || -      cast<Instruction>(ShuffleInst->getOperand(0))->getOpcode() != -      Instruction::InsertElement) +  Value *GEPPtrs = GEP->getPointerOperand(); +  if (!(Ptr = getSplatValue(GEPPtrs)))      return false; -  Ptr = cast<InsertElementInst>(ShuffleInst->getOperand(0))->getOperand(1); -    SelectionDAG& DAG = SDB->DAG;    const TargetLowering &TLI = DAG.getTargetLoweringInfo();    // Check is the Ptr is inside current basic block    // If not, look for the shuffle instruction    if (SDB->findValue(Ptr))      Base = SDB->getValue(Ptr); -  else if (SDB->findValue(ShuffleInst)) { -    SDValue ShuffleNode = SDB->getValue(ShuffleInst); -    SDLoc sdl = ShuffleNode; -    Base = DAG.getNode( -        ISD::EXTRACT_VECTOR_ELT, sdl, -        ShuffleNode.getValueType().getScalarType(), ShuffleNode, -        DAG.getConstant(0, sdl, TLI.getVectorIdxTy(DAG.getDataLayout()))); +  else if (SDB->findValue(GEPPtrs)) { +    SDValue GEPPtrsVal = SDB->getValue(GEPPtrs); +    SDLoc sdl = GEPPtrsVal; +    EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout()); +    Base = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, sdl, +                       GEPPtrsVal.getValueType().getScalarType(), GEPPtrsVal, +                       DAG.getConstant(0, sdl, IdxVT));      SDB->setValue(Ptr, Base);    }    else      return false; -  Value *IndexVal = Gep->getOperand(1); +  Value *IndexVal = GEP->getOperand(1);    if (SDB->findValue(IndexVal)) {      Index = SDB->getValue(IndexVal);  | 

