67 Value *B0 =
nullptr, *B1 =
nullptr;
85 NarrowedLeafShifts.
empty())
87 unsigned NumLeaves = NarrowedLeafShifts.
size();
90 for (
const auto &[V, L] : NarrowedLeafShifts) {
91 if (L.Shift >= NumLeaves || Seen.
test(L.Shift))
96 if ((L.Mask & ~
Known.Zero).ugt(1))
113 if (Leaves.
size() < 2)
115 Type *FieldTy = Leaves.
front().V->getType();
120 return A.Shift <
B.Shift;
122 for (
const auto &[Pos, L] :
enumerate(Leaves))
123 if (L.V->getType() != FieldTy || !L.Mask.isAllOnes() ||
137 unsigned VF = VecTy->getNumElements();
139 DebugLoc DL = Builder.getCurrentDebugLocation();
141 Value *
T = Builder.CreateTrunc(Vec, I1VecTy);
142 Value *BC = Builder.CreateBitCast(
T, Builder.getIntNTy(VF));
148 Value *Res = Builder.CreateICmp(Pred, BC, RHS);
151 auto CastCost = [&](
Value *V,
unsigned Opcode,
Type *SrcTy) {
155 return TTI.getCastInstrCost(Opcode,
I->getType(), SrcTy,
156 TTI.getCastContextHint(
I), CostKind,
I);
159 CastCost(BC, Instruction::BitCast, I1VecTy);
161 BitcastCmpCost +=
TTI.getCmpSelInstrCost(
162 Instruction::ICmp, BC->
getType(),
nullptr, Pred, CostKind,
163 TTI.getOperandInfo(BC),
TTI.getOperandInfo(RHS), Cmp);
164 if (BitcastCmpCost >=
166 for (
Value *V : {Res, BC,
T})
168 I->eraseFromParent();
169 Builder.SetCurrentDebugLocation(
DL);
172 Builder.SetCurrentDebugLocation(
DL);
181 auto DominatedReduxValue = [&](
Value *R) {
189 if (
P->getIncomingBlock(0) == ParentBB) {
191 }
else if (
P->getIncomingBlock(1) == ParentBB) {
195 if (Rdx && DominatedReduxValue(Rdx))
208 if (
P->getIncomingBlock(0) == BBLatch) {
210 }
else if (
P->getIncomingBlock(1) == BBLatch) {
214 if (Rdx && DominatedReduxValue(Rdx))
228 while (!Worklist.
empty()) {
234 I->getParent() == Root->
getParent() &&
I->hasOneUse() &&
241 constexpr unsigned MinReducedVals = 4;
244 if (RdxVals.
size() < MinReducedVals || !L || L->contains(Root) ||
255 if (Acc || !
P ||
P->getParent() != L->getHeader() || !
P->hasOneUse())
263 PHINode *Acc = GetAccumulator(RdxVal);
271 while (!Stack.empty()) {
272 auto [
I,
Depth] = Stack.pop_back_val();
289 Stack.emplace_back(OpI,
Depth + 1);
295 else if (RdxShape != Shape)
299 LoadInst *Ld0 = Loads.front()[Pos];
300 SmallVector<int64_t> Offsets;
301 for (ArrayRef<LoadInst *> RdxLoads : Loads) {
302 std::optional<int64_t> Diff = getPointersDiff(
303 Ld0->getType(), Ld0->getPointerOperand(), RdxLoads[Pos]->getType(),
304 RdxLoads[Pos]->getPointerOperand(), DL, SE);
307 Offsets.push_back(*Diff);
311 return P.value() == Offsets.front() +
static_cast<int64_t
>(
P.index());
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
SmallVector< MachineOperand, 4 > Cond
Provides some synthesis utilities to produce sequences of values.
This file implements the SmallBitVector class.
LLVM Basic Block Representation.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Convenience struct for specifying and reasoning about fast-math flags.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Common base class shared among various IRBuilders.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool isIdenticalTo(const Instruction *I) const LLVM_READONLY
Return true if the specified instruction is exactly identical to the current one.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
The main scalar evolution driver.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
iterator_range< user_iterator > users()
const ParentTy * getParent() const
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
auto m_UMin(const Opnd0 &Op0, const Opnd1 &Op1)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_SMax(const Opnd0 &Op0, const Opnd1 &Op1)
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_UMax(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_FMinimum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
auto m_FMaximum(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_FMinNum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_SMin(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
auto m_FMaxNum(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
A private "module" namespace for types and utilities used by this pass.
bool matchPackedFields(Value *V, unsigned MaxDepth, SmallVectorImpl< Value * > &Fields, SmallVectorImpl< Instruction * > &Chain)
Matches V as the zero-extended fields, placed one after another from the lowest bit and filling V com...
Instruction * getReductionInstr(const DominatorTree *DT, PHINode *P, BasicBlock *ParentBB, LoopInfo *LI)
Try to get a reduction instruction from phi node P in block ParentBB, considering incoming values fro...
Type * getBoolReduxWideTy(RecurKind RdxKind, Type *RootTy, Type *LeafTy)
Value * tryEmitBoolReduxBitcastCmp(IRBuilderBase &Builder, const TargetTransformInfo &TTI, RecurKind RdxKind, Value *Vec, const Value *Root, FastMathFlags FMF, const TTI::TargetCostKind CostKind)
Emits the booleanized logical and/or reduction of Vec with the i1 root Root as trunc+bitcast+cmp (all...
bool isReductionOfConsecutiveAccumulators(Instruction *Root, const LoopInfo &LI, const DataLayout &DL, ScalarEvolution &SE, unsigned MaxDepth, SmallVectorImpl< unsigned > &Shape, SmallPtrSetImpl< PHINode * > &Accs)
Checks if the reduction, rooted at Root, reduces the loop accumulators, whose updates are the same ex...
BoolBitmask isBoolBitmaskRdx(RecurKind RdxKind, const SmallDenseMap< Value *, NarrowedLeafInfo > &NarrowedLeafShifts, const DataLayout &DL)
InstructionCost getBoolReduxWideRdxCost(const TargetTransformInfo &TTI, RecurKind RdxKind, FixedVectorType *VecTy, const Value *Root, FastMathFlags FMF, const TTI::TargetCostKind CostKind)
Returns the cost of the booleanized logical and/or reduction of a vector of type VecTy with the i1 ro...
RecurKind getRdxKind(Value *V)
Gets recurrence kind from the specified value.
static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1)
Instruction * getNonPhiOperand(Instruction *I, PHINode *Phi)
bool isReductionCandidate(Instruction *I)
void collectNarrowedLeaves(Value *V, unsigned RdxOpcode, unsigned WideBW, unsigned MaxDepth, SmallVectorImpl< NarrowedLeafInfo > &Leaves, SmallVectorImpl< Instruction * > &ChainInsts)
Recursively collects the narrow leaves of the widened reduction value V.
BoolBitmask
The result of matching a boolean bitmask reduction over narrowed leaves.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
@ Known
Known to have no common set bits.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Or
Bitwise or logical OR of integers.
@ FMinimum
FP min with llvm.minimum semantics.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ FMin
FP min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Narrow reduction leaf: the value, the shift applied after widening and the mask applied in the narrow...