LLVM  10.0.0svn
Classes | Macros | Typedefs | Functions
InstCombineVectorOps.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <utility>
Include dependency graph for InstCombineVectorOps.cpp:

Go to the source code of this file.

Classes

struct  BinopElts
 These are the ingredients in an alternate form binary operator as described below. More...
 

Macros

#define DEBUG_TYPE   "instcombine"
 

Typedefs

using ShuffleOps = std::pair< Value *, Value * >
 We are building a shuffle to create V, which is a sequence of insertelement, extractelement pairs. More...
 

Functions

static bool cheapToScalarize (Value *V, bool IsConstantExtractIndex)
 Return true if the value is cheaper to scalarize than it is to leave as a vector operation. More...
 
static InstructionfoldBitcastExtElt (ExtractElementInst &Ext, InstCombiner::BuilderTy &Builder, bool IsBigEndian)
 
static bool collectSingleShuffleElements (Value *V, Value *LHS, Value *RHS, SmallVectorImpl< Constant *> &Mask)
 If V is a shuffle of values that ONLY returns elements from either LHS or RHS, return the shuffle mask and true. More...
 
static void replaceExtractElements (InsertElementInst *InsElt, ExtractElementInst *ExtElt, InstCombiner &IC)
 If we have insertion into a vector that is wider than the vector that we are extracting from, try to widen the source vector to allow a single shufflevector to replace one or more insert/extract pairs. More...
 
static ShuffleOps collectShuffleElements (Value *V, SmallVectorImpl< Constant *> &Mask, Value *PermittedRHS, InstCombiner &IC)
 
static bool isShuffleEquivalentToSelect (ShuffleVectorInst &Shuf)
 
static InstructionfoldInsSequenceIntoSplat (InsertElementInst &InsElt)
 Turn a chain of inserts that splats a value into an insert + shuffle: insertelt(insertelt(insertelt(insertelt X, k, 0), k, 1), k, 2) ... More...
 
static InstructionfoldInsEltIntoSplat (InsertElementInst &InsElt)
 Try to fold an insert element into an existing splat shuffle by changing the shuffle's mask to include the index of this insert element. More...
 
static InstructionfoldInsEltIntoIdentityShuffle (InsertElementInst &InsElt)
 Try to fold an extract+insert element into an existing identity shuffle by changing the shuffle's mask to include the index of this insert element. More...
 
static InstructionhoistInsEltConst (InsertElementInst &InsElt2, InstCombiner::BuilderTy &Builder)
 If we have an insertelement instruction feeding into another insertelement and the 2nd is inserting a constant into the vector, canonicalize that constant insertion before the insertion of a variable: More...
 
static InstructionfoldConstantInsEltIntoShuffle (InsertElementInst &InsElt)
 insertelt (shufflevector X, CVec, Mask|insertelt X, C1, CIndex1), C, CIndex –> shufflevector X, CVec', Mask' More...
 
static bool canEvaluateShuffled (Value *V, ArrayRef< int > Mask, unsigned Depth=5)
 Return true if we can evaluate the specified expression tree if the vector elements were shuffled in a different order. More...
 
static ValuebuildNew (Instruction *I, ArrayRef< Value *> NewOps)
 Rebuild a new instruction just like 'I' but with the new operands given. More...
 
static ValueevaluateInDifferentElementOrder (Value *V, ArrayRef< int > Mask)
 
static void recognizeIdentityMask (const SmallVectorImpl< int > &Mask, bool &isLHSID, bool &isRHSID)
 
static bool isShuffleExtractingFromLHS (ShuffleVectorInst &SVI, SmallVector< int, 16 > &Mask)
 
static BinopElts getAlternateBinop (BinaryOperator *BO, const DataLayout &DL)
 Binops may be transformed into binops with different opcodes and operands. More...
 
static InstructionfoldSelectShuffleWith1Binop (ShuffleVectorInst &Shuf)
 
static InstructioncanonicalizeInsertSplat (ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
 If we have an insert of a scalar to a non-zero element of an undefined vector and then shuffle that value, that's the same as inserting to the zero element and shuffling. More...
 
static InstructionfoldSelectShuffle (ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
 Try to fold shuffles that are the equivalent of a vector select. More...
 
static InstructionnarrowVectorSelect (ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
 Match a shuffle-select-shuffle pattern where the shuffles are widening and narrowing (concatenating with undef and extracting back to the original length). More...
 
static InstructionfoldIdentityExtractShuffle (ShuffleVectorInst &Shuf)
 Try to combine 2 shuffles into 1 shuffle by concatenating a shuffle mask. More...
 
static InstructionfoldShuffleWithInsert (ShuffleVectorInst &Shuf)
 Try to replace a shuffle with an insertelement. More...
 
static InstructionfoldIdentityPaddedShuffles (ShuffleVectorInst &Shuf)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 45 of file InstCombineVectorOps.cpp.

Typedef Documentation

◆ ShuffleOps

using ShuffleOps = std::pair<Value *, Value *>

We are building a shuffle to create V, which is a sequence of insertelement, extractelement pairs.

If PermittedRHS is set, then we must either use it or not rely on the second vector source. Return a std::pair containing the left and right vectors of the proposed shuffle (or 0), and set the Mask parameter as required.

Note: we intentionally don't try to fold earlier shuffles since they have often been chosen carefully to be efficiently implementable on the target.

Definition at line 525 of file InstCombineVectorOps.cpp.

Function Documentation

◆ buildNew()

static Value* buildNew ( Instruction I,
ArrayRef< Value *>  NewOps 
)
static

◆ canEvaluateShuffled()

static bool canEvaluateShuffled ( Value V,
ArrayRef< int >  Mask,
unsigned  Depth = 5 
)
static

◆ canonicalizeInsertSplat()

static Instruction* canonicalizeInsertSplat ( ShuffleVectorInst Shuf,
InstCombiner::BuilderTy Builder 
)
static

◆ cheapToScalarize()

static bool cheapToScalarize ( Value V,
bool  IsConstantExtractIndex 
)
static

◆ collectShuffleElements()

static ShuffleOps collectShuffleElements ( Value V,
SmallVectorImpl< Constant *> &  Mask,
Value PermittedRHS,
InstCombiner IC 
)
static

◆ collectSingleShuffleElements()

static bool collectSingleShuffleElements ( Value V,
Value LHS,
Value RHS,
SmallVectorImpl< Constant *> &  Mask 
)
static

If V is a shuffle of values that ONLY returns elements from either LHS or RHS, return the shuffle mask and true.

Otherwise, return false.

Definition at line 366 of file InstCombineVectorOps.cpp.

References assert(), llvm::SmallVectorImpl< T >::assign(), llvm::ConstantInt::get(), llvm::UndefValue::get(), llvm::Value::getContext(), llvm::Type::getInt32Ty(), llvm::User::getOperand(), llvm::Value::getType(), llvm::Type::getVectorNumElements(), and llvm::SmallVectorTemplateBase< T >::push_back().

Referenced by collectShuffleElements().

◆ evaluateInDifferentElementOrder()

static Value* evaluateInDifferentElementOrder ( Value V,
ArrayRef< int >  Mask 
)
static

◆ foldBitcastExtElt()

static Instruction* foldBitcastExtElt ( ExtractElementInst Ext,
InstCombiner::BuilderTy Builder,
bool  IsBigEndian 
)
static

◆ foldConstantInsEltIntoShuffle()

static Instruction* foldConstantInsEltIntoShuffle ( InsertElementInst InsElt)
static

◆ foldIdentityExtractShuffle()

static Instruction* foldIdentityExtractShuffle ( ShuffleVectorInst Shuf)
static

◆ foldIdentityPaddedShuffles()

static Instruction* foldIdentityPaddedShuffles ( ShuffleVectorInst Shuf)
static

◆ foldInsEltIntoIdentityShuffle()

static Instruction* foldInsEltIntoIdentityShuffle ( InsertElementInst InsElt)
static

◆ foldInsEltIntoSplat()

static Instruction* foldInsEltIntoSplat ( InsertElementInst InsElt)
static

◆ foldInsSequenceIntoSplat()

static Instruction* foldInsSequenceIntoSplat ( InsertElementInst InsElt)
static

Turn a chain of inserts that splats a value into an insert + shuffle: insertelt(insertelt(insertelt(insertelt X, k, 0), k, 1), k, 2) ...

-> shufflevector(insertelt(X, k, 0), undef, zero)

Definition at line 668 of file InstCombineVectorOps.cpp.

References llvm::any_of(), llvm::InsertElementInst::Create(), llvm::dyn_cast(), llvm::ConstantInt::get(), llvm::ConstantVector::get(), llvm::UndefValue::get(), llvm::Value::getContext(), llvm::Type::getInt32Ty(), llvm::User::getOperand(), llvm::InsertElementInst::getType(), llvm::Value::hasOneUse(), Int32Ty, isZero(), llvm::BitmaskEnumDetail::Mask(), and llvm::Instruction::user_back().

Referenced by llvm::InstCombiner::visitInsertElementInst().

◆ foldSelectShuffle()

static Instruction* foldSelectShuffle ( ShuffleVectorInst Shuf,
InstCombiner::BuilderTy Builder,
const DataLayout DL 
)
static

◆ foldSelectShuffleWith1Binop()

static Instruction* foldSelectShuffleWith1Binop ( ShuffleVectorInst Shuf)
static

◆ foldShuffleWithInsert()

static Instruction* foldShuffleWithInsert ( ShuffleVectorInst Shuf)
static

◆ getAlternateBinop()

static BinopElts getAlternateBinop ( BinaryOperator BO,
const DataLayout DL 
)
static

Binops may be transformed into binops with different opcodes and operands.

Reverse the usual canonicalization to enable folds with the non-canonical form of the binop. If a transform is possible, return the elements of the new binop. If not, return invalid elements.

Definition at line 1360 of file InstCombineVectorOps.cpp.

References llvm::MCID::Add, C, llvm::ConstantInt::get(), llvm::BinaryOperator::getOpcode(), llvm::User::getOperand(), llvm::ConstantExpr::getShl(), llvm::Value::getType(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_Constant(), llvm::MaskedValueIsZero(), and llvm::PatternMatch::match().

Referenced by foldSelectShuffle().

◆ hoistInsEltConst()

static Instruction* hoistInsEltConst ( InsertElementInst InsElt2,
InstCombiner::BuilderTy Builder 
)
static

If we have an insertelement instruction feeding into another insertelement and the 2nd is inserting a constant into the vector, canonicalize that constant insertion before the insertion of a variable:

insertelement (insertelement X, Y, IdxC1), ScalarC, IdxC2 –> insertelement (insertelement X, ScalarC, IdxC2), Y, IdxC1

This has the potential of eliminating the 2nd insertelement instruction via constant folding of the scalar constant into a vector constant.

Definition at line 827 of file InstCombineVectorOps.cpp.

References llvm::InsertElementInst::Create(), llvm::IRBuilder< T, Inserter >::CreateInsertElement(), llvm::dyn_cast(), llvm::User::getOperand(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), X, and Y.

Referenced by llvm::InstCombiner::visitInsertElementInst().

◆ isShuffleEquivalentToSelect()

static bool isShuffleEquivalentToSelect ( ShuffleVectorInst Shuf)
static

◆ isShuffleExtractingFromLHS()

static bool isShuffleExtractingFromLHS ( ShuffleVectorInst SVI,
SmallVector< int, 16 > &  Mask 
)
static

◆ narrowVectorSelect()

static Instruction* narrowVectorSelect ( ShuffleVectorInst Shuf,
InstCombiner::BuilderTy Builder 
)
static

Match a shuffle-select-shuffle pattern where the shuffles are widening and narrowing (concatenating with undef and extracting back to the original length).

This allows replacing the wide select with a narrow select.

Definition at line 1601 of file InstCombineVectorOps.cpp.

References llvm::User::getOperand(), llvm::ShuffleVectorInst::isIdentityWithExtract(), llvm::PatternMatch::m_Undef(), and llvm::PatternMatch::match().

Referenced by llvm::InstCombiner::visitShuffleVectorInst().

◆ recognizeIdentityMask()

static void recognizeIdentityMask ( const SmallVectorImpl< int > &  Mask,
bool isLHSID,
bool isRHSID 
)
static

◆ replaceExtractElements()

static void replaceExtractElements ( InsertElementInst InsElt,
ExtractElementInst ExtElt,
InstCombiner IC 
)
static