LLVM  14.0.0git
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/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.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/InstCombiner.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <utility>
#include "llvm/Transforms/Utils/InstructionWorklist.h"
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

 STATISTIC (NumAggregateReconstructionsSimplified, "Number of aggregate reconstructions turned into reuse of the " "original aggregate")
 
static bool cheapToScalarize (Value *V, Value *EI)
 Return true if the value is cheaper to scalarize than it is to leave as a vector operation. More...
 
static APInt findDemandedEltsBySingleUser (Value *V, Instruction *UserInstr)
 Find elements of V demanded by UserInstr. More...
 
static APInt findDemandedEltsByAllUsers (Value *V)
 Find union of elements of V demanded by all its users. More...
 
static bool collectSingleShuffleElements (Value *V, Value *LHS, Value *RHS, SmallVectorImpl< int > &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, InstCombinerImpl &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< int > &Mask, Value *PermittedRHS, InstCombinerImpl &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 InstructionnarrowInsElt (InsertElementInst &InsElt, InstCombiner::BuilderTy &Builder)
 If both the base vector and the inserted element are extended from the same type, do the insert element in the narrow source type followed by extend. 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 bool isShuffleExtractingFromLHS (ShuffleVectorInst &SVI, ArrayRef< int > 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 InstructionfoldTruncShuffle (ShuffleVectorInst &Shuf, bool IsBigEndian)
 Convert a narrowing shuffle of a bitcasted vector into a vector truncate. 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 fold an extract subvector operation. More...
 
static InstructionfoldShuffleWithInsert (ShuffleVectorInst &Shuf, InstCombinerImpl &IC)
 Try to replace a shuffle with an insertelement or try to replace a shuffle operand with the operand of an insertelement. More...
 
static InstructionfoldIdentityPaddedShuffles (ShuffleVectorInst &Shuf)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 44 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 715 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

Return true if we can evaluate the specified expression tree if the vector elements were shuffled in a different order.

Definition at line 1597 of file InstCombineVectorOps.cpp.

References llvm::MCID::Add, llvm::Depth, llvm::numbers::e, llvm::ConstantInt::getLimitedValue(), i, I, llvm::is_contained(), llvm::Type::isVectorTy(), LLVM_FALLTHROUGH, and llvm::BitmaskEnumDetail::Mask().

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

◆ canonicalizeInsertSplat()

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

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.

Splatting from the zero element is recognized as the canonical form of splat.

Definition at line 1978 of file InstCombineVectorOps.cpp.

References Builder, llvm::UndefValue::get(), llvm::User::getOperand(), llvm::ShuffleVectorInst::getShuffleMask(), llvm::ShuffleVectorInst::getType(), i, llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_InsertElt(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Undef(), llvm::PatternMatch::m_Value(), llvm::BitmaskEnumDetail::Mask(), llvm::PatternMatch::match(), llvm::UndefMaskElem, and X.

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

◆ cheapToScalarize()

static bool cheapToScalarize ( Value V,
Value EI 
)
static

Return true if the value is cheaper to scalarize than it is to leave as a vector operation.

If the extract index EI is a constant integer then some operations may be cheap to scalarize.

FIXME: It's possible to create more instructions than previously existed.

Definition at line 59 of file InstCombineVectorOps.cpp.

References llvm::Constant::getSplatValue(), llvm::Value::getType(), llvm::ConstantInt::getValue(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_Cmp(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_InsertElt(), llvm::PatternMatch::m_Load(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_UnOp(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), and llvm::APInt::ult().

Referenced by llvm::InstCombinerImpl::visitExtractElementInst().

◆ collectShuffleElements()

static ShuffleOps collectShuffleElements ( Value V,
SmallVectorImpl< int > &  Mask,
Value PermittedRHS,
InstCombinerImpl IC 
)
static

◆ collectSingleShuffleElements()

static bool collectSingleShuffleElements ( Value V,
Value LHS,
Value RHS,
SmallVectorImpl< int > &  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 562 of file InstCombineVectorOps.cpp.

References assert(), llvm::User::getOperand(), llvm::Value::getType(), i, llvm::PatternMatch::m_Undef(), llvm::BitmaskEnumDetail::Mask(), and llvm::PatternMatch::match().

Referenced by collectShuffleElements().

◆ evaluateInDifferentElementOrder()

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

◆ findDemandedEltsByAllUsers()

static APInt findDemandedEltsByAllUsers ( Value V)
static

Find union of elements of V demanded by all its users.

If it is known by querying findDemandedEltsBySingleUser that no user demands an element of V, then the corresponding bit remains unset in the returned value.

Definition at line 347 of file InstCombineVectorOps.cpp.

References findDemandedEltsBySingleUser(), llvm::APInt::getAllOnes(), llvm::Value::getType(), I, llvm::APInt::isAllOnes(), and llvm::Value::uses().

Referenced by llvm::InstCombinerImpl::visitExtractElementInst().

◆ findDemandedEltsBySingleUser()

static APInt findDemandedEltsBySingleUser ( Value V,
Instruction UserInstr 
)
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

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.

Definition at line 1253 of file InstCombineVectorOps.cpp.

References assert(), llvm::User::getOperand(), i, llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_ExtractElt(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Undef(), llvm::PatternMatch::match(), llvm::UndefMaskElem, and X.

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

◆ foldInsEltIntoSplat()

static Instruction* foldInsEltIntoSplat ( InsertElementInst InsElt)
static

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.

Definition at line 1216 of file InstCombineVectorOps.cpp.

References llvm::User::getOperand(), i, llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_InsertElt(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_Undef(), llvm::PatternMatch::m_ZeroInt(), llvm::PatternMatch::match(), and X.

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

◆ foldInsSequenceIntoSplat()

static Instruction* foldInsSequenceIntoSplat ( InsertElementInst InsElt)
static

◆ 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,
InstCombinerImpl IC 
)
static

◆ foldTruncShuffle()

static Instruction* foldTruncShuffle ( ShuffleVectorInst Shuf,
bool  IsBigEndian 
)
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 1896 of file InstCombineVectorOps.cpp.

References llvm::MCID::Add, DL, 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 1312 of file InstCombineVectorOps.cpp.

References Builder, llvm::InsertElementInst::Create(), llvm::User::getOperand(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), X, and Y.

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

◆ isShuffleEquivalentToSelect()

static bool isShuffleEquivalentToSelect ( ShuffleVectorInst Shuf)
static

◆ isShuffleExtractingFromLHS()

static bool isShuffleExtractingFromLHS ( ShuffleVectorInst SVI,
ArrayRef< int Mask 
)
static

◆ narrowInsElt()

static Instruction* narrowInsElt ( InsertElementInst InsElt,
InstCombiner::BuilderTy Builder 
)
static

If both the base vector and the inserted element are extended from the same type, do the insert element in the narrow source type followed by extend.

TODO: This can be extended to include other cast opcodes, but particularly if we create a wider insertelement, make sure codegen is not harmed.

Definition at line 1439 of file InstCombineVectorOps.cpp.

References Builder, llvm::CastInst::Create(), llvm::User::getOperand(), llvm::InsertElementInst::getType(), llvm::Value::hasOneUse(), llvm::PatternMatch::m_FPExt(), llvm::PatternMatch::m_SExt(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_ZExt(), llvm::PatternMatch::match(), X, and Y.

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

◆ 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 2182 of file InstCombineVectorOps.cpp.

References Builder, Cond, llvm::SelectInst::Create(), llvm::User::getOperand(), llvm::ShuffleVectorInst::getShuffleMask(), llvm::Value::getType(), llvm::ShuffleVectorInst::getType(), llvm::ShuffleVectorInst::isIdentityWithExtract(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Select(), llvm::PatternMatch::m_Shuffle(), llvm::PatternMatch::m_Undef(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), X, and Y.

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

◆ replaceExtractElements()

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

◆ STATISTIC()

STATISTIC ( NumAggregateReconstructionsSimplified  ,
"Number of aggregate reconstructions turned into reuse of the " "original aggregate"   
)