LLVM 24.0.0git
SLPReductionUtils.cpp
Go to the documentation of this file.
1//===- SLPReductionUtils.cpp - SLP reduction match helpers ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "SLPReductionUtils.h"
10
11#include "SLPCostAnalysis.h"
12#include "SLPUtils.h"
13
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/Sequence.h"
21#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/Dominators.h"
24#include "llvm/IR/IRBuilder.h"
26#include "llvm/IR/Intrinsics.h"
28#include "llvm/IR/Type.h"
29
30using namespace llvm;
31using namespace llvm::PatternMatch;
32
33namespace llvm::slpvectorizer {
34
35static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
36 if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
37 return true;
38 if (match(I, m_FMaxNum(m_Value(V0), m_Value(V1))))
39 return true;
40 if (match(I, m_FMinNum(m_Value(V0), m_Value(V1))))
41 return true;
42 if (match(I, m_FMaximum(m_Value(V0), m_Value(V1))))
43 return true;
44 if (match(I, m_FMinimum(m_Value(V0), m_Value(V1))))
45 return true;
47 return true;
49 return true;
51 return true;
53 return true;
54 return false;
55}
56
58 Value *Op0 = nullptr;
59 Value *Op1 = nullptr;
60 if (!matchRdxBop(I, Op0, Op1))
61 return nullptr;
62 return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);
63}
64
66 bool IsSelect = match(I, m_Select(m_Value(), m_Value(), m_Value()));
67 Value *B0 = nullptr, *B1 = nullptr;
68 bool IsBinop = matchRdxBop(I, B0, B1);
69 return IsBinop || IsSelect;
70}
71
72Type *getBoolReduxWideTy(RecurKind RdxKind, Type *RootTy, Type *LeafTy) {
73 if ((RdxKind == RecurKind::And || RdxKind == RecurKind::Or) &&
74 RootTy->isIntegerTy(1) && LeafTy->isIntegerTy() &&
75 !LeafTy->isIntegerTy(1))
76 return LeafTy;
77 return nullptr;
78}
79
81 RecurKind RdxKind,
82 const SmallDenseMap<Value *, NarrowedLeafInfo> &NarrowedLeafShifts,
83 const DataLayout &DL) {
84 if (RdxKind != RecurKind::Or || DL.isBigEndian() ||
85 NarrowedLeafShifts.empty())
86 return BoolBitmask::None;
87 unsigned NumLeaves = NarrowedLeafShifts.size();
88 SmallBitVector Seen(NumLeaves);
89 bool NeedMask = false;
90 for (const auto &[V, L] : NarrowedLeafShifts) {
91 if (L.Shift >= NumLeaves || Seen.test(L.Shift))
92 return BoolBitmask::None;
93 Seen.set(L.Shift);
95 // The masked leaf must be known to be 0 or 1.
96 if ((L.Mask & ~Known.Zero).ugt(1))
97 return BoolBitmask::None;
98 // The mask is redundant if it keeps all not-known-zero bits.
99 NeedMask |= !(Known.Zero | L.Mask).isAllOnes();
100 }
102}
103
104bool matchPackedFields(Value *V, unsigned MaxDepth,
107 auto *PackTy = dyn_cast<IntegerType>(V->getType());
108 if (!PackTy)
109 return false;
111 collectNarrowedLeaves(V, Instruction::Or, PackTy->getBitWidth(), MaxDepth,
112 Leaves, Chain);
113 if (Leaves.size() < 2)
114 return false;
115 Type *FieldTy = Leaves.front().V->getType();
116 if (!FieldTy->isIntegerTy() ||
117 PackTy->getBitWidth() != Leaves.size() * FieldTy->getIntegerBitWidth())
118 return false;
119 llvm::sort(Leaves, [](const NarrowedLeafInfo &A, const NarrowedLeafInfo &B) {
120 return A.Shift < B.Shift;
121 });
122 for (const auto &[Pos, L] : enumerate(Leaves))
123 if (L.V->getType() != FieldTy || !L.Mask.isAllOnes() ||
124 L.Shift != Pos * FieldTy->getIntegerBitWidth())
125 return false;
127 Fields, map_range(Leaves, [](const NarrowedLeafInfo &L) { return L.V; }));
128 return true;
129}
130
133 RecurKind RdxKind, Value *Vec,
134 const Value *Root, FastMathFlags FMF,
135 const TTI::TargetCostKind CostKind) {
136 auto *VecTy = cast<FixedVectorType>(Vec->getType());
137 unsigned VF = VecTy->getNumElements();
138 auto *I1VecTy = FixedVectorType::get(Builder.getInt1Ty(), VF);
139 DebugLoc DL = Builder.getCurrentDebugLocation();
140 Builder.SetCurrentDebugLocation(cast<Instruction>(Root)->getDebugLoc());
141 Value *T = Builder.CreateTrunc(Vec, I1VecTy);
142 Value *BC = Builder.CreateBitCast(T, Builder.getIntNTy(VF));
143 CmpInst::Predicate Pred =
145 Constant *RHS = RdxKind == RecurKind::And
148 Value *Res = Builder.CreateICmp(Pred, BC, RHS);
149 // The costs are evaluated from the emitted instructions; they are dropped
150 // if the wide reduction form is cheaper.
151 auto CastCost = [&](Value *V, unsigned Opcode, Type *SrcTy) {
152 auto *I = dyn_cast<Instruction>(V);
153 if (!I)
154 return InstructionCost(0);
155 return TTI.getCastInstrCost(Opcode, I->getType(), SrcTy,
156 TTI.getCastContextHint(I), CostKind, I);
157 };
158 InstructionCost BitcastCmpCost = CastCost(T, Instruction::Trunc, VecTy) +
159 CastCost(BC, Instruction::BitCast, I1VecTy);
160 if (auto *Cmp = dyn_cast<Instruction>(Res))
161 BitcastCmpCost += TTI.getCmpSelInstrCost(
162 Instruction::ICmp, BC->getType(), /*CondTy=*/nullptr, Pred, CostKind,
163 TTI.getOperandInfo(BC), TTI.getOperandInfo(RHS), Cmp);
164 if (BitcastCmpCost >=
165 getBoolReduxWideRdxCost(TTI, RdxKind, VecTy, Root, FMF, CostKind)) {
166 for (Value *V : {Res, BC, T})
167 if (auto *I = dyn_cast<Instruction>(V))
168 I->eraseFromParent();
169 Builder.SetCurrentDebugLocation(DL);
170 return nullptr;
171 }
172 Builder.SetCurrentDebugLocation(DL);
173 return Res;
174}
175
177 BasicBlock *ParentBB, LoopInfo *LI) {
178 // There are situations where the reduction value is not dominated by the
179 // reduction phi. Vectorizing such cases has been reported to cause
180 // miscompiles. See PR25787.
181 auto DominatedReduxValue = [&](Value *R) {
182 return isa<Instruction>(R) &&
183 DT->dominates(P->getParent(), cast<Instruction>(R)->getParent());
184 };
185
186 Instruction *Rdx = nullptr;
187
188 // Return the incoming value if it comes from the same BB as the phi node.
189 if (P->getIncomingBlock(0) == ParentBB) {
190 Rdx = dyn_cast<Instruction>(P->getIncomingValue(0));
191 } else if (P->getIncomingBlock(1) == ParentBB) {
192 Rdx = dyn_cast<Instruction>(P->getIncomingValue(1));
193 }
194
195 if (Rdx && DominatedReduxValue(Rdx))
196 return Rdx;
197
198 // Otherwise, check whether we have a loop latch to look at.
199 Loop *BBL = LI->getLoopFor(ParentBB);
200 if (!BBL)
201 return nullptr;
202 BasicBlock *BBLatch = BBL->getLoopLatch();
203 if (!BBLatch)
204 return nullptr;
205
206 // There is a loop latch, return the incoming value if it comes from
207 // that. This reduction pattern occasionally turns up.
208 if (P->getIncomingBlock(0) == BBLatch) {
209 Rdx = dyn_cast<Instruction>(P->getIncomingValue(0));
210 } else if (P->getIncomingBlock(1) == BBLatch) {
211 Rdx = dyn_cast<Instruction>(P->getIncomingValue(1));
212 }
213
214 if (Rdx && DominatedReduxValue(Rdx))
215 return Rdx;
216
217 return nullptr;
218}
219
221 const DataLayout &DL,
222 ScalarEvolution &SE,
223 unsigned MaxDepth,
227 SmallVector<Instruction *> Worklist(1, Root);
228 while (!Worklist.empty()) {
229 for (Value *Op : Worklist.pop_back_val()->operands()) {
230 auto *I = dyn_cast<Instruction>(Op);
231 if (!I)
232 return false;
233 if (I->getOpcode() == Root->getOpcode() &&
234 I->getParent() == Root->getParent() && I->hasOneUse() &&
236 Worklist.push_back(I);
237 else
238 RdxVals.push_back(I);
239 }
240 }
241 constexpr unsigned MinReducedVals = 4;
242 BasicBlock *BB = RdxVals.front()->getParent();
243 const Loop *L = LI.getLoopFor(BB);
244 if (RdxVals.size() < MinReducedVals || !L || L->contains(Root) ||
245 any_of(RdxVals, [&](Instruction *I) { return I->getParent() != BB; }))
246 return false;
247 // The accumulators, used by the other ones, cannot be vectorized along the
248 // reduced values without the shuffles in the loop.
249 auto GetAccumulator = [&](Instruction *RdxVal) -> PHINode * {
250 PHINode *Acc = nullptr;
251 for (User *U : RdxVal->users()) {
252 if (!L->contains(cast<Instruction>(U)))
253 continue;
254 auto *P = dyn_cast<PHINode>(U);
255 if (Acc || !P || P->getParent() != L->getHeader() || !P->hasOneUse())
256 return nullptr;
257 Acc = P;
258 }
259 return Acc;
260 };
262 for (Instruction *RdxVal : RdxVals) {
263 PHINode *Acc = GetAccumulator(RdxVal);
264 if (!Acc)
265 return false;
266 Accs.insert(Acc);
267 SmallVectorImpl<LoadInst *> &RdxLoads = Loads.emplace_back();
268 SmallVector<unsigned> RdxShape;
271 while (!Stack.empty()) {
272 auto [I, Depth] = Stack.pop_back_val();
273 if (!Visited.insert(I).second)
274 continue;
275 if (I != Acc && isa<PHINode>(I) && I->getParent() == L->getHeader())
276 return false;
277 if (auto *LdI = dyn_cast<LoadInst>(I)) {
278 RdxLoads.push_back(LdI);
279 RdxShape.push_back(I->getOpcode());
280 continue;
281 }
282 if (Depth == MaxDepth || isa<PHINode>(I) || I->getParent() != BB)
283 continue;
284 RdxShape.push_back(I->getOpcode());
285 if (auto *Cmp = dyn_cast<CmpInst>(I))
286 RdxShape.push_back(Cmp->getPredicate());
287 for (Value *Op : reverse(I->operands()))
288 if (auto *OpI = dyn_cast<Instruction>(Op))
289 Stack.emplace_back(OpI, Depth + 1);
290 }
291 if (RdxLoads.empty() || !Visited.contains(Acc))
292 return false;
293 if (Shape.empty())
294 Shape.assign(RdxShape.begin(), RdxShape.end());
295 else if (RdxShape != Shape)
296 return false;
297 }
298 return all_of(seq<unsigned>(Loads.front().size()), [&](unsigned Pos) {
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);
305 if (!Diff)
306 return false;
307 Offsets.push_back(*Diff);
308 }
309 sort(Offsets);
310 return all_of(enumerate(Offsets), [&](const auto &P) {
311 return P.value() == Offsets.front() + static_cast<int64_t>(P.index());
312 });
313 });
314}
315
317 auto *I = dyn_cast<Instruction>(V);
318 if (!I)
319 return RecurKind::None;
320 if (match(I, m_Add(m_Value(), m_Value())))
321 return RecurKind::Add;
322 if (match(I, m_Mul(m_Value(), m_Value())))
323 return RecurKind::Mul;
324 if (match(I, m_And(m_Value(), m_Value())) ||
326 return RecurKind::And;
327 if (match(I, m_Or(m_Value(), m_Value())) ||
329 return RecurKind::Or;
330 if (match(I, m_Xor(m_Value(), m_Value())))
331 return RecurKind::Xor;
332 if (match(I, m_FAdd(m_Value(), m_Value())))
333 return RecurKind::FAdd;
334 if (match(I, m_FMul(m_Value(), m_Value())))
335 return RecurKind::FMul;
336
338 return RecurKind::FMax;
340 return RecurKind::FMin;
341
342 if (match(I, m_FMaximum(m_Value(), m_Value())))
343 return RecurKind::FMaximum;
344 if (match(I, m_FMinimum(m_Value(), m_Value())))
345 return RecurKind::FMinimum;
346 // TODO: remove several special-case paths that deal with selects.
347 if (match(I, m_SMax(m_Value(), m_Value())))
348 return RecurKind::SMax;
349 if (match(I, m_SMin(m_Value(), m_Value())))
350 return RecurKind::SMin;
351 if (match(I, m_UMax(m_Value(), m_Value())))
352 return RecurKind::UMax;
353 if (match(I, m_UMin(m_Value(), m_Value())))
354 return RecurKind::UMin;
355
356 if (auto *Select = dyn_cast<SelectInst>(I)) {
357 // Try harder: look for min/max pattern based on instructions producing
358 // same values such as: select ((cmp Inst1, Inst2), Inst1, Inst2).
359 // During the intermediate stages of SLP, it's very common to have
360 // pattern like this (since optimizeGatherSequence is run only once
361 // at the end):
362 // %1 = extractelement <2 x i32> %a, i32 0
363 // %2 = extractelement <2 x i32> %a, i32 1
364 // %cond = icmp sgt i32 %1, %2
365 // %3 = extractelement <2 x i32> %a, i32 0
366 // %4 = extractelement <2 x i32> %a, i32 1
367 // %select = select i1 %cond, i32 %3, i32 %4
368 CmpPredicate Pred;
369 Instruction *L1;
370 Instruction *L2;
371
372 Value *LHS = Select->getTrueValue();
373 Value *RHS = Select->getFalseValue();
374 Value *Cond = Select->getCondition();
375
376 // TODO: Support inverse predicates.
377 if (match(Cond, m_Cmp(Pred, m_Specific(LHS), m_Instruction(L2)))) {
378 if (!isa<ExtractElementInst>(RHS) ||
380 return RecurKind::None;
381 } else if (match(Cond, m_Cmp(Pred, m_Instruction(L1), m_Specific(RHS)))) {
382 if (!isa<ExtractElementInst>(LHS) ||
384 return RecurKind::None;
385 } else {
387 return RecurKind::None;
388 if (!match(Cond, m_Cmp(Pred, m_Instruction(L1), m_Instruction(L2))) ||
389 !L1->isIdenticalTo(cast<Instruction>(LHS)) ||
391 return RecurKind::None;
392 }
393
394 switch (Pred) {
395 default:
396 return RecurKind::None;
399 return RecurKind::SMax;
402 return RecurKind::SMin;
405 return RecurKind::UMax;
408 return RecurKind::UMin;
409 }
410 }
411 return RecurKind::None;
412}
413
414} // namespace llvm::slpvectorizer
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")
#define I(x, y, z)
Definition MD5.cpp:57
#define T
#define P(N)
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
SmallVector< MachineOperand, 4 > Cond
Func MI getDebugLoc()))
This file contains some templates that are useful if you are working with the STL at all.
Provides some synthesis utilities to produce sequences of values.
This file implements the SmallBitVector class.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
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.
Definition Constant.h:44
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.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
bool empty() const
Definition DenseMap.h:716
unsigned size() const
Definition DenseMap.h:717
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
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.
Definition FMF.h:23
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
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.
Definition LoopInfo.h:40
The main scalar evolution driver.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
SmallBitVector & set()
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.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
iterator_range< user_iterator > users()
Definition Value.h:428
const ParentTy * getParent() const
Definition ilist_node.h:34
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.
Definition STLExtras.h:1755
@ 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,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
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.
Definition STLExtras.h:366
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
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...
Definition Casting.h:547
TargetTransformInfo TTI
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.
@ None
Not a recurrence.
@ Xor
Bitwise or logical XOR of integers.
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ FMul
Product of floats.
@ 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()).
@ Add
Sum of integers.
@ FAdd
Sum of floats.
@ 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.
Definition Casting.h:559
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
Narrow reduction leaf: the value, the shift applied after widening and the mask applied in the narrow...
Definition SLPUtils.h:460