LLVM 24.0.0git
SDPatternMatch.h
Go to the documentation of this file.
1//==--------------- llvm/CodeGen/SDPatternMatch.h ---------------*- C++ -*-===//
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/// \file
9/// Contains matchers for matching SelectionDAG nodes and values.
10///
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_SDPATTERNMATCH_H
14#define LLVM_CODEGEN_SDPATTERNMATCH_H
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/bit.h"
25
26#include <type_traits>
27
28namespace llvm {
29namespace SDPatternMatch {
30
31template <typename Pattern>
32[[nodiscard]] bool sd_match(SDValue N, Pattern &&P) {
33 return P.match(N);
34}
35
36template <typename Pattern>
37[[nodiscard]] bool sd_match(SDNode *N, Pattern &&P) {
38 return sd_match(SDValue(N, 0), P);
39}
40
41// === Utilities ===
44
45 Value_match() = default;
46
47 explicit Value_match(SDValue Match) : MatchVal(Match) {}
48
49 bool match(SDValue N) {
50 if (MatchVal)
51 return MatchVal == N;
52 return N.getNode();
53 }
54};
55
56/// Match any valid SDValue.
57inline Value_match m_Value() { return Value_match(); }
58
60 assert(N);
61 return Value_match(N);
62}
63
64template <unsigned ResNo, typename Pattern> struct Result_match {
66
67 explicit Result_match(const Pattern &P) : P(P) {}
68
69 bool match(SDValue N) { return N.getResNo() == ResNo && P.match(N); }
70};
71
72/// Match only if the SDValue is a certain result at ResNo.
73template <unsigned ResNo, typename Pattern>
77
80
81 explicit DeferredValue_match(SDValue &Match) : MatchVal(Match) {}
82
83 bool match(SDValue N) { return N == MatchVal; }
84};
85
86/// Similar to m_Specific, but the specific value to match is determined by
87/// another sub-pattern in the same sd_match() expression. For instance,
88/// We cannot match `(add V, V)` with `m_Add(m_Value(X), m_Specific(X))` since
89/// `X` is not initialized at the time it got copied into `m_Specific`. Instead,
90/// we should use `m_Add(m_Value(X), m_Deferred(X))`.
94
96 unsigned Opcode;
97
98 explicit Opcode_match(unsigned Opc) : Opcode(Opc) {}
99
100 bool match(SDValue N) { return N->getOpcode() == Opcode; }
101};
102
103// === Patterns combinators ===
104template <typename... Preds> struct And {
105 bool match(SDValue N) { return true; }
106};
107
108template <typename Pred, typename... Preds>
109struct And<Pred, Preds...> : And<Preds...> {
110 Pred P;
111 And(const Pred &p, const Preds &...preds) : And<Preds...>(preds...), P(p) {}
112
113 bool match(SDValue N) { return P.match(N) && And<Preds...>::match(N); }
114};
115
116template <typename... Preds> struct Or {
117 bool match(SDValue N) { return false; }
118};
119
120template <typename Pred, typename... Preds>
121struct Or<Pred, Preds...> : Or<Preds...> {
122 Pred P;
123 Or(const Pred &p, const Preds &...preds) : Or<Preds...>(preds...), P(p) {}
124
125 bool match(SDValue N) { return P.match(N) || Or<Preds...>::match(N); }
126};
127
128template <typename Pred> struct Not {
129 Pred P;
130
131 explicit Not(const Pred &P) : P(P) {}
132
133 bool match(SDValue N) { return !P.match(N); }
134};
135// Explicit deduction guide.
136template <typename Pred> Not(const Pred &P) -> Not<Pred>;
137
138/// Match if the inner pattern does NOT match.
139template <typename Pred> inline Not<Pred> m_Unless(const Pred &P) {
140 return Not{P};
141}
142
143template <typename... Preds> And<Preds...> m_AllOf(const Preds &...preds) {
144 return And<Preds...>(preds...);
145}
146
147template <typename... Preds> Or<Preds...> m_AnyOf(const Preds &...preds) {
148 return Or<Preds...>(preds...);
149}
150
151template <typename... Preds> auto m_NoneOf(const Preds &...preds) {
152 return m_Unless(m_AnyOf(preds...));
153}
154
155inline Opcode_match m_SpecificOpc(unsigned Opcode) {
156 return Opcode_match(Opcode);
157}
158
159inline auto m_Undef() {
161}
162
164
165template <unsigned NumUses, typename Pattern> struct NUses_match {
167
168 explicit NUses_match(const Pattern &P) : P(P) {}
169
171 // SDNode::hasNUsesOfValue is pretty expensive when the SDNode produces
172 // multiple results, hence we check the subsequent pattern here before
173 // checking the number of value users.
174 return P.match(N) && N->hasNUsesOfValue(NumUses, N.getResNo());
175 }
176};
177
178template <typename Pattern>
182template <unsigned N, typename Pattern>
186
190template <unsigned N> inline NUses_match<N, Value_match> m_NUses() {
192}
193
196
198
200 BindVal = N;
201 return true;
202 }
203};
204
205inline auto m_Value(SDValue &N) { return Value_bind(N); }
206/// Conditionally bind an SDValue based on the predicate.
207template <typename PredPattern>
208inline auto m_Value(SDValue &N, const PredPattern &P) {
209 return m_AllOf(P, Value_bind(N));
210}
211
212template <typename Pattern, typename PredFuncT> struct TLI_pred_match {
214 PredFuncT PredFunc;
215
216 TLI_pred_match(const PredFuncT &Pred, const Pattern &P)
217 : P(P), PredFunc(Pred) {}
218
219 bool match(SDValue N) { return PredFunc(N) && P.match(N); }
220};
221
222// Explicit deduction guide.
223template <typename PredFuncT, typename Pattern>
224TLI_pred_match(const PredFuncT &Pred, const Pattern &P)
226
227/// Match legal SDNodes based on the information provided by TargetLowering.
228template <typename Pattern>
229inline auto m_LegalOp(const SelectionDAG &DAG, const Pattern &P) {
230 return TLI_pred_match{[&DAG](SDValue N) {
232 N->getOpcode(), N.getValueType());
233 },
234 P};
235}
236
237// === Value type ===
238
239template <typename Pattern> struct ValueType_bind {
242
243 explicit ValueType_bind(EVT &Bind, const Pattern &P) : BindVT(Bind), P(P) {}
244
246 BindVT = N.getValueType();
247 return P.match(N);
248 }
249};
250
251template <typename Pattern>
253
254/// Retreive the ValueType of the current SDValue.
255inline auto m_VT(EVT &VT) { return ValueType_bind(VT, m_Value()); }
256
257template <typename Pattern> inline auto m_VT(EVT &VT, const Pattern &P) {
258 return ValueType_bind(VT, P);
259}
260
261template <typename Pattern, typename PredFuncT> struct ValueType_match {
262 PredFuncT PredFunc;
264
265 ValueType_match(const PredFuncT &Pred, const Pattern &P)
266 : PredFunc(Pred), P(P) {}
267
268 bool match(SDValue N) { return PredFunc(N.getValueType()) && P.match(N); }
269};
270
271// Explicit deduction guide.
272template <typename PredFuncT, typename Pattern>
273ValueType_match(const PredFuncT &Pred, const Pattern &P)
275
276/// Match a specific ValueType.
277template <typename Pattern>
278inline auto m_SpecificVT(EVT RefVT, const Pattern &P) {
279 return ValueType_match{[=](EVT VT) { return VT == RefVT; }, P};
280}
281inline auto m_SpecificVT(EVT RefVT) {
282 return ValueType_match{[=](EVT VT) { return VT == RefVT; }, m_Value()};
283}
284
285inline auto m_Glue() { return m_SpecificVT(MVT::Glue); }
286inline auto m_OtherVT() { return m_SpecificVT(MVT::Other); }
287
288/// Match a scalar ValueType.
289template <typename Pattern>
290inline auto m_SpecificScalarVT(EVT RefVT, const Pattern &P) {
291 return ValueType_match{[=](EVT VT) { return VT.getScalarType() == RefVT; },
292 P};
293}
294inline auto m_SpecificScalarVT(EVT RefVT) {
295 return ValueType_match{[=](EVT VT) { return VT.getScalarType() == RefVT; },
296 m_Value()};
297}
298
299/// Match a vector ValueType.
300template <typename Pattern>
301inline auto m_SpecificVectorElementVT(EVT RefVT, const Pattern &P) {
302 return ValueType_match{[=](EVT VT) {
303 return VT.isVector() &&
304 VT.getVectorElementType() == RefVT;
305 },
306 P};
307}
308inline auto m_SpecificVectorElementVT(EVT RefVT) {
309 return ValueType_match{[=](EVT VT) {
310 return VT.isVector() &&
311 VT.getVectorElementType() == RefVT;
312 },
313 m_Value()};
314}
315
316/// Match any integer ValueTypes.
317template <typename Pattern> inline auto m_IntegerVT(const Pattern &P) {
318 return ValueType_match{[](EVT VT) { return VT.isInteger(); }, P};
319}
320inline auto m_IntegerVT() {
321 return ValueType_match{[](EVT VT) { return VT.isInteger(); }, m_Value()};
322}
323
324/// Match any floating point ValueTypes.
325template <typename Pattern> inline auto m_FloatingPointVT(const Pattern &P) {
326 return ValueType_match{[](EVT VT) { return VT.isFloatingPoint(); }, P};
327}
328inline auto m_FloatingPointVT() {
329 return ValueType_match{[](EVT VT) { return VT.isFloatingPoint(); },
330 m_Value()};
331}
332
333/// Match any vector ValueTypes.
334template <typename Pattern> inline auto m_VectorVT(const Pattern &P) {
335 return ValueType_match{[](EVT VT) { return VT.isVector(); }, P};
336}
337inline auto m_VectorVT() {
338 return ValueType_match{[](EVT VT) { return VT.isVector(); }, m_Value()};
339}
340
341/// Match fixed-length vector ValueTypes.
342template <typename Pattern> inline auto m_FixedVectorVT(const Pattern &P) {
343 return ValueType_match{[](EVT VT) { return VT.isFixedLengthVector(); }, P};
344}
345inline auto m_FixedVectorVT() {
346 return ValueType_match{[](EVT VT) { return VT.isFixedLengthVector(); },
347 m_Value()};
348}
349
350/// Match scalable vector ValueTypes.
351template <typename Pattern> inline auto m_ScalableVectorVT(const Pattern &P) {
352 return ValueType_match{[](EVT VT) { return VT.isScalableVector(); }, P};
353}
354inline auto m_ScalableVectorVT() {
355 return ValueType_match{[](EVT VT) { return VT.isScalableVector(); },
356 m_Value()};
357}
358
359/// Match legal ValueTypes based on the information provided by TargetLowering.
360template <typename Pattern>
361inline auto m_LegalType(const SelectionDAG &DAG, const Pattern &P) {
362 return TLI_pred_match{[&DAG](SDValue N) {
364 N.getValueType());
365 },
366 P};
367}
368
369// === Generic node matching ===
370template <unsigned OpIdx, typename... OpndPreds> struct Operands_match {
372 // Returns false if there are more operands than predicates;
373 return N->getNumOperands() == OpIdx;
374 }
375};
376
377template <unsigned OpIdx, typename OpndPred, typename... OpndPreds>
378struct Operands_match<OpIdx, OpndPred, OpndPreds...>
379 : Operands_match<OpIdx + 1, OpndPreds...> {
380 OpndPred P;
381
382 Operands_match(const OpndPred &p, const OpndPreds &...preds)
383 : Operands_match<OpIdx + 1, OpndPreds...>(preds...), P(p) {}
384
386 if (OpIdx < N->getNumOperands())
387 return P.match(N->getOperand(OpIdx)) &&
389
390 // This is the case where there are more predicates than operands.
391 return false;
392 }
393};
394
395template <typename... OpndPreds>
396auto m_Node(unsigned Opcode, const OpndPreds &...preds) {
397 return m_AllOf(m_SpecificOpc(Opcode),
399}
400
401/// Provide number of operands that are not chain or glue, as well as the first
402/// index of such operand.
403template <bool ExcludeChain> struct EffectiveOperands {
404 unsigned Size = 0;
405 unsigned FirstIndex = 0;
406
407 explicit EffectiveOperands(SDValue N) : Size(N->getNumOperands()) {
408 if (ExcludeChain) {
409 // Glue if present, is the last operand.
410 if (Size != 0 && N->getOperand(Size - 1).getValueType() == MVT::Glue)
411 --Size;
412 // Chain if present, is the first operand.
413 if (Size != 0 && N->getOperand(0).getValueType() == MVT::Other) {
414 ++FirstIndex;
415 --Size;
416 }
417 }
418 }
419};
420
421// === Ternary operations ===
422template <typename T0_P, typename T1_P, typename T2_P, bool Commutable = false,
423 bool ExcludeChain = false>
425 unsigned Opcode;
426 T0_P Op0;
427 T1_P Op1;
428 T2_P Op2;
429
430 TernaryOpc_match(unsigned Opc, const T0_P &Op0, const T1_P &Op1,
431 const T2_P &Op2)
432 : Opcode(Opc), Op0(Op0), Op1(Op1), Op2(Op2) {}
433
437 assert(EO.Size == 3);
438 return ((Op0.match(N->getOperand(EO.FirstIndex)) &&
439 Op1.match(N->getOperand(EO.FirstIndex + 1))) ||
440 (Commutable && Op0.match(N->getOperand(EO.FirstIndex + 1)) &&
441 Op1.match(N->getOperand(EO.FirstIndex)))) &&
442 Op2.match(N->getOperand(EO.FirstIndex + 2));
443 }
444
445 return false;
446 }
447};
448
450 std::optional<ISD::CondCode> CCToMatch;
452
454
455 explicit CondCode_match(ISD::CondCode *CC) : BindCC(CC) {}
456
458 if (auto *CC = dyn_cast<CondCodeSDNode>(N.getNode())) {
459 if (CCToMatch && *CCToMatch != CC->get())
460 return false;
461
462 if (BindCC)
463 *BindCC = CC->get();
464 return true;
465 }
466
467 return false;
468 }
469};
470
471/// Match any conditional code SDNode.
472inline CondCode_match m_CondCode() { return CondCode_match(nullptr); }
473/// Match any conditional code SDNode and return its ISD::CondCode value.
475 return CondCode_match(&CC);
476}
477/// Match a conditional code SDNode with a specific ISD::CondCode.
481
482/// Match a SETCC with any condition code.
483template <typename T0_P, typename T1_P>
489
490/// Match a SETCC with any condition code and bind the condition code to CC.
491template <typename T0_P, typename T1_P>
492inline TernaryOpc_match<T0_P, T1_P, CondCode_match>
493m_SetCC(ISD::CondCode &CC, const T0_P &LHS, const T1_P &RHS) {
495 m_CondCode(CC));
496}
497
498/// Match a SETCC with a specific condition code.
499template <typename T0_P, typename T1_P>
500inline TernaryOpc_match<T0_P, T1_P, CondCode_match>
505
506/// Match a SETCC with any condition code, allowing the operands to be
507/// commuted.
508template <typename T0_P, typename T1_P>
509inline TernaryOpc_match<T0_P, T1_P, CondCode_match, true, false>
514
515/// Match a SETCC with any condition code, allowing the operands to be
516/// commuted, and bind the condition code to CC.
517template <typename T0_P, typename T1_P>
518inline TernaryOpc_match<T0_P, T1_P, CondCode_match, true, false>
523
524/// Match a SETCC with a specific condition code, allowing the operands to be
525/// commuted.
526template <typename T0_P, typename T1_P>
527inline TernaryOpc_match<T0_P, T1_P, CondCode_match, true, false>
532
533template <typename T0_P, typename T1_P, typename T2_P>
534inline TernaryOpc_match<T0_P, T1_P, T2_P>
535m_Select(const T0_P &Cond, const T1_P &T, const T2_P &F) {
537}
538
539template <typename T0_P, typename T1_P, typename T2_P>
540inline TernaryOpc_match<T0_P, T1_P, T2_P>
541m_VSelect(const T0_P &Cond, const T1_P &T, const T2_P &F) {
543}
544
545template <typename T0_P, typename T1_P, typename T2_P>
546inline auto m_SelectLike(const T0_P &Cond, const T1_P &T, const T2_P &F) {
547 return m_AnyOf(m_Select(Cond, T, F), m_VSelect(Cond, T, F));
548}
549
550template <typename T0_P, typename T1_P, typename T2_P>
551inline Result_match<0, TernaryOpc_match<T0_P, T1_P, T2_P>>
552m_Load(const T0_P &Ch, const T1_P &Ptr, const T2_P &Offset) {
553 return m_Result<0>(
555}
556
557template <typename T0_P, typename T1_P, typename T2_P>
558inline TernaryOpc_match<T0_P, T1_P, T2_P>
559m_InsertElt(const T0_P &Vec, const T1_P &Val, const T2_P &Idx) {
561 Idx);
562}
563
564template <typename LHS, typename RHS, typename IDX>
565inline TernaryOpc_match<LHS, RHS, IDX>
566m_InsertSubvector(const LHS &Base, const RHS &Sub, const IDX &Idx) {
568}
569
570template <typename T0_P, typename T1_P, typename T2_P>
571inline TernaryOpc_match<T0_P, T1_P, T2_P>
572m_SpliceRight(const T0_P &V1, const T1_P &V2, const T2_P &Offset) {
574 Offset);
575}
576
577template <typename T0_P, typename T1_P, typename T2_P>
578inline TernaryOpc_match<T0_P, T1_P, T2_P>
579m_TernaryOp(unsigned Opc, const T0_P &Op0, const T1_P &Op1, const T2_P &Op2) {
580 return TernaryOpc_match<T0_P, T1_P, T2_P>(Opc, Op0, Op1, Op2);
581}
582
583template <typename T0_P, typename T1_P, typename T2_P>
584inline TernaryOpc_match<T0_P, T1_P, T2_P, true>
585m_c_TernaryOp(unsigned Opc, const T0_P &Op0, const T1_P &Op1, const T2_P &Op2) {
586 return TernaryOpc_match<T0_P, T1_P, T2_P, true>(Opc, Op0, Op1, Op2);
587}
588
589/// Match a SELECT_CC with any condition code.
590template <typename LTy, typename RTy, typename TTy, typename FTy>
591inline auto m_SelectCC(const LTy &L, const RTy &R, const TTy &T, const FTy &F) {
592 return m_Node(ISD::SELECT_CC, L, R, T, F, m_CondCode());
593}
594
595/// Match a SELECT_CC with any condition code and bind the condition code to
596/// CC.
597template <typename LTy, typename RTy, typename TTy, typename FTy>
598inline auto m_SelectCC(ISD::CondCode &CC, const LTy &L, const RTy &R,
599 const TTy &T, const FTy &F) {
600 return m_Node(ISD::SELECT_CC, L, R, T, F, m_CondCode(CC));
601}
602
603/// Match a SELECT_CC with a specific condition code.
604template <typename LTy, typename RTy, typename TTy, typename FTy>
605inline auto m_SpecificSelectCC(ISD::CondCode CC, const LTy &L, const RTy &R,
606 const TTy &T, const FTy &F) {
607 return m_Node(ISD::SELECT_CC, L, R, T, F, m_SpecificCondCode(CC));
608}
609
610/// Match a SELECT of a SETCC or a SELECT_CC with any condition code.
611template <typename LTy, typename RTy, typename TTy, typename FTy>
612inline auto m_SelectCCLike(const LTy &L, const RTy &R, const TTy &T,
613 const FTy &F) {
614 return m_AnyOf(m_Select(m_SetCC(L, R), T, F), m_SelectCC(L, R, T, F));
615}
616
617/// Match a SELECT of a SETCC or a SELECT_CC with any condition code and bind
618/// the condition code to CC.
619template <typename LTy, typename RTy, typename TTy, typename FTy>
620inline auto m_SelectCCLike(ISD::CondCode &CC, const LTy &L, const RTy &R,
621 const TTy &T, const FTy &F) {
622 return m_AnyOf(m_Select(m_SetCC(CC, L, R), T, F), m_SelectCC(CC, L, R, T, F));
623}
624
625/// Match a SELECT of a SETCC or a SELECT_CC with a specific condition code.
626template <typename LTy, typename RTy, typename TTy, typename FTy>
627inline auto m_SpecificSelectCCLike(ISD::CondCode CC, const LTy &L, const RTy &R,
628 const TTy &T, const FTy &F) {
629 return m_AnyOf(m_Select(m_SpecificSetCC(CC, L, R), T, F),
630 m_SpecificSelectCC(CC, L, R, T, F));
631}
632
633// === Binary operations ===
634template <typename LHS_P, typename RHS_P, bool Commutable = false,
635 bool ExcludeChain = false>
637 unsigned Opcode;
638 LHS_P LHS;
639 RHS_P RHS;
641 BinaryOpc_match(unsigned Opc, const LHS_P &L, const RHS_P &R,
642 SDNodeFlags Flgs = SDNodeFlags())
643 : Opcode(Opc), LHS(L), RHS(R), Flags(Flgs) {}
644
648 assert(EO.Size == 2);
649 if (!((LHS.match(N->getOperand(EO.FirstIndex)) &&
650 RHS.match(N->getOperand(EO.FirstIndex + 1))) ||
651 (Commutable && LHS.match(N->getOperand(EO.FirstIndex + 1)) &&
652 RHS.match(N->getOperand(EO.FirstIndex)))))
653 return false;
654
655 return (Flags & N->getFlags()) == Flags;
656 }
657
658 return false;
659 }
660};
661
662/// Matching while capturing mask
663template <typename T0, typename T1, typename T2> struct SDShuffle_match {
664 T0 Op1;
667
668 SDShuffle_match(const T0 &Op1, const T1 &Op2, const T2 &Mask)
669 : Op1(Op1), Op2(Op2), Mask(Mask) {}
670
672 if (auto *I = dyn_cast<ShuffleVectorSDNode>(N)) {
673 return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1)) &&
674 Mask.match(I->getMask());
675 }
676 return false;
677 }
678};
679struct m_Mask {
682 bool match(ArrayRef<int> Mask) {
683 MaskRef = Mask;
684 return true;
685 }
686};
687
693
694template <typename LHS_P, typename RHS_P, typename Pred_t,
695 bool Commutable = false>
697 using PredType = Pred_t;
698 LHS_P LHS;
699 RHS_P RHS;
700
701 MaxMin_match(const LHS_P &L, const RHS_P &R) : LHS(L), RHS(R) {}
702
704 auto MatchMinMax = [&](SDValue L, SDValue R, SDValue TrueValue,
705 SDValue FalseValue, ISD::CondCode CC) {
706 if ((TrueValue != L || FalseValue != R) &&
707 (TrueValue != R || FalseValue != L))
708 return false;
709
711 TrueValue == L ? CC : getSetCCInverse(CC, L.getValueType());
712 if (!Pred_t::match(Cond))
713 return false;
714
715 return (LHS.match(L) && RHS.match(R)) ||
716 (Commutable && LHS.match(R) && RHS.match(L));
717 };
718
719 if (N.getOpcode() == ISD::SELECT || N.getOpcode() == ISD::VSELECT) {
720 assert(N.getNumOperands() == 3);
721 SDValue Cond = N.getOperand(0);
722 SDValue TrueValue = N.getOperand(1);
723 SDValue FalseValue = N.getOperand(2);
724
725 if (Cond.getOpcode() == ISD::SETCC) {
726 assert(Cond.getNumOperands() == 3);
727 SDValue L = Cond.getOperand(0);
728 SDValue R = Cond.getOperand(1);
729 ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
730 return MatchMinMax(L, R, TrueValue, FalseValue, CC);
731 }
732 }
733
734 if (N.getOpcode() == ISD::SELECT_CC) {
735 assert(N.getNumOperands() == 5);
736 SDValue L = N.getOperand(0);
737 SDValue R = N.getOperand(1);
738 SDValue TrueValue = N.getOperand(2);
739 SDValue FalseValue = N.getOperand(3);
740 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
741 return MatchMinMax(L, R, TrueValue, FalseValue, CC);
742 }
743
744 return false;
745 }
746};
747
748// Helper class for identifying signed max predicates.
750 static bool match(ISD::CondCode Cond) {
752 }
753};
754
755// Helper class for identifying unsigned max predicates.
760};
761
762// Helper class for identifying signed min predicates.
764 static bool match(ISD::CondCode Cond) {
766 }
767};
768
769// Helper class for identifying unsigned min predicates.
774};
775
776template <typename LHS, typename RHS>
777inline BinaryOpc_match<LHS, RHS> m_BinOp(unsigned Opc, const LHS &L,
778 const RHS &R,
779 SDNodeFlags Flgs = SDNodeFlags()) {
780 return BinaryOpc_match<LHS, RHS>(Opc, L, R, Flgs);
781}
782template <typename LHS, typename RHS>
784m_c_BinOp(unsigned Opc, const LHS &L, const RHS &R,
785 SDNodeFlags Flgs = SDNodeFlags()) {
786 return BinaryOpc_match<LHS, RHS, true>(Opc, L, R, Flgs);
787}
788
789template <typename LHS, typename RHS>
791m_ChainedBinOp(unsigned Opc, const LHS &L, const RHS &R) {
793}
794template <typename LHS, typename RHS>
796m_c_ChainedBinOp(unsigned Opc, const LHS &L, const RHS &R) {
798}
799
800// Common binary operations
801template <typename LHS, typename RHS>
802inline BinaryOpc_match<LHS, RHS, true> m_Add(const LHS &L, const RHS &R) {
804}
805
806template <typename LHS, typename RHS>
807inline auto m_NUWAdd(const LHS &L, const RHS &R) {
810}
811
812template <typename LHS, typename RHS>
813inline auto m_NSWAdd(const LHS &L, const RHS &R) {
816}
817
818template <typename LHS, typename RHS>
819inline BinaryOpc_match<LHS, RHS> m_Sub(const LHS &L, const RHS &R) {
821}
822
823template <typename LHS, typename RHS>
824inline BinaryOpc_match<LHS, RHS, true> m_Mul(const LHS &L, const RHS &R) {
826}
827
828template <typename LHS, typename RHS>
829inline BinaryOpc_match<LHS, RHS, true> m_And(const LHS &L, const RHS &R) {
831}
832
833template <typename LHS, typename RHS>
834inline BinaryOpc_match<LHS, RHS, true> m_Or(const LHS &L, const RHS &R) {
836}
837
838template <typename LHS, typename RHS>
843
844template <typename LHS, typename RHS>
845inline auto m_AddLike(const LHS &L, const RHS &R) {
846 return m_AnyOf(m_Add(L, R), m_DisjointOr(L, R));
847}
848
849template <typename LHS, typename RHS>
850inline auto m_NSWAddLike(const LHS &L, const RHS &R) {
851 return m_AnyOf(m_NSWAdd(L, R), m_DisjointOr(L, R));
852}
853
854template <typename LHS, typename RHS>
855inline auto m_NUWAddLike(const LHS &L, const RHS &R) {
856 return m_AnyOf(m_NUWAdd(L, R), m_DisjointOr(L, R));
857}
858
859template <typename LHS, typename RHS>
860inline BinaryOpc_match<LHS, RHS, true> m_Xor(const LHS &L, const RHS &R) {
862}
863
864template <typename LHS, typename RHS>
865inline auto m_BitwiseLogic(const LHS &L, const RHS &R) {
866 return m_AnyOf(m_And(L, R), m_Or(L, R), m_Xor(L, R));
867}
868
869template <unsigned Opc, typename Pred, typename LHS, typename RHS>
870inline auto m_MaxMinLike(const LHS &L, const RHS &R) {
873}
874
875template <typename LHS, typename RHS>
876inline BinaryOpc_match<LHS, RHS, true> m_SMin(const LHS &L, const RHS &R) {
878}
879
880template <typename LHS, typename RHS>
881inline auto m_SMinLike(const LHS &L, const RHS &R) {
883}
884
885template <typename LHS, typename RHS>
886inline BinaryOpc_match<LHS, RHS, true> m_SMax(const LHS &L, const RHS &R) {
888}
889
890template <typename LHS, typename RHS>
891inline auto m_SMaxLike(const LHS &L, const RHS &R) {
893}
894
895template <typename LHS, typename RHS>
896inline BinaryOpc_match<LHS, RHS, true> m_UMin(const LHS &L, const RHS &R) {
898}
899
900template <typename LHS, typename RHS>
901inline auto m_UMinLike(const LHS &L, const RHS &R) {
903}
904
905template <typename LHS, typename RHS>
906inline BinaryOpc_match<LHS, RHS, true> m_UMax(const LHS &L, const RHS &R) {
908}
909
910template <typename LHS, typename RHS>
911inline auto m_UMaxLike(const LHS &L, const RHS &R) {
913}
914
915template <typename LHS, typename RHS>
916inline BinaryOpc_match<LHS, RHS> m_UDiv(const LHS &L, const RHS &R) {
918}
919template <typename LHS, typename RHS>
920inline BinaryOpc_match<LHS, RHS> m_SDiv(const LHS &L, const RHS &R) {
922}
923
924template <typename LHS, typename RHS>
925inline BinaryOpc_match<LHS, RHS> m_URem(const LHS &L, const RHS &R) {
927}
928template <typename LHS, typename RHS>
929inline BinaryOpc_match<LHS, RHS> m_SRem(const LHS &L, const RHS &R) {
931}
932
933template <typename LHS, typename RHS>
934inline BinaryOpc_match<LHS, RHS> m_Shl(const LHS &L, const RHS &R) {
936}
937
938template <typename LHS, typename RHS>
939inline BinaryOpc_match<LHS, RHS> m_Sra(const LHS &L, const RHS &R) {
941}
942template <typename LHS, typename RHS>
943inline BinaryOpc_match<LHS, RHS> m_Srl(const LHS &L, const RHS &R) {
945}
946template <typename LHS, typename RHS>
951
952template <typename LHS, typename RHS>
953inline BinaryOpc_match<LHS, RHS> m_Rotl(const LHS &L, const RHS &R) {
955}
956
957template <typename LHS, typename RHS>
958inline BinaryOpc_match<LHS, RHS> m_Rotr(const LHS &L, const RHS &R) {
960}
961
962template <typename T0_P, typename T1_P, typename T2_P>
963inline TernaryOpc_match<T0_P, T1_P, T2_P>
964m_FShL(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2) {
965 return m_TernaryOp(ISD::FSHL, Op0, Op1, Op2);
966}
967
968template <typename T0_P, typename T1_P, typename T2_P>
969inline TernaryOpc_match<T0_P, T1_P, T2_P>
970m_FShR(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2) {
971 return m_TernaryOp(ISD::FSHR, Op0, Op1, Op2);
972}
973
974template <typename T0_P, typename T1_P, typename T2_P, bool Left>
976 T0_P Op0;
977 T1_P Op1;
978 T2_P Op2;
979
980 FunnelShiftLike_match(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
981 : Op0(Op0), Op1(Op1), Op2(Op2) {}
982
983 static bool hasComplementaryConstantShifts(const APInt &ShlV,
984 const APInt &SrlV,
985 unsigned BitWidth) {
986 unsigned SumWidth = std::max(ShlV.getBitWidth(), SrlV.getBitWidth()) + 1;
987 unsigned BitWidthBits = llvm::bit_width(BitWidth);
988 if (BitWidthBits > SumWidth)
989 return false;
990
991 return ShlV.zext(SumWidth) + SrlV.zext(SumWidth) ==
992 APInt(SumWidth, BitWidth);
993 }
994
996 return Op0.match(X) && Op1.match(Y) && Op2.match(Z);
997 }
998
999 bool matchShiftOr(SDValue N, unsigned BitWidth);
1000
1002 if (sd_match(N, Left ? m_FShL(Op0, Op1, Op2) : m_FShR(Op0, Op1, Op2)))
1003 return true;
1004
1005 SDValue X, Z;
1006 if (sd_match(N, Left ? m_Rotl(m_Value(X), m_Value(Z))
1007 : m_Rotr(m_Value(X), m_Value(Z))))
1008 return matchOperands(X, X, Z);
1009
1010 return matchShiftOr(N, N.getValueType().getScalarSizeInBits());
1011 }
1012};
1013
1014template <typename T0_P, typename T1_P, typename T2_P>
1015inline FunnelShiftLike_match<T0_P, T1_P, T2_P, true>
1016m_FShLLike(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2) {
1018}
1019
1020template <typename T0_P, typename T1_P, typename T2_P>
1021inline FunnelShiftLike_match<T0_P, T1_P, T2_P, false>
1022m_FShRLike(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2) {
1024}
1025
1026template <typename LHS, typename RHS>
1029}
1030
1031template <typename LHS, typename RHS>
1032inline BinaryOpc_match<LHS, RHS, true> m_FAdd(const LHS &L, const RHS &R) {
1034}
1035
1036template <typename LHS, typename RHS>
1037inline BinaryOpc_match<LHS, RHS> m_FSub(const LHS &L, const RHS &R) {
1039}
1040
1041template <typename LHS, typename RHS>
1042inline BinaryOpc_match<LHS, RHS, true> m_FMul(const LHS &L, const RHS &R) {
1044}
1045
1046template <typename LHS, typename RHS>
1047inline BinaryOpc_match<LHS, RHS> m_FDiv(const LHS &L, const RHS &R) {
1049}
1050
1051template <typename LHS, typename RHS>
1052inline BinaryOpc_match<LHS, RHS> m_FRem(const LHS &L, const RHS &R) {
1054}
1055
1056template <typename V1_t, typename V2_t>
1057inline BinaryOpc_match<V1_t, V2_t> m_Shuffle(const V1_t &v1, const V2_t &v2) {
1059}
1060
1061template <typename V1_t, typename V2_t, typename Mask_t>
1062inline SDShuffle_match<V1_t, V2_t, Mask_t>
1063m_Shuffle(const V1_t &v1, const V2_t &v2, const Mask_t &mask) {
1065}
1066
1067template <typename LHS, typename RHS>
1068inline BinaryOpc_match<LHS, RHS> m_ExtractElt(const LHS &Vec, const RHS &Idx) {
1070}
1071
1072template <typename LHS, typename RHS>
1074 const RHS &Idx) {
1076}
1077
1078// === Unary operations ===
1079template <typename Opnd_P, bool ExcludeChain = false> struct UnaryOpc_match {
1080 unsigned Opcode;
1081 Opnd_P Opnd;
1083 UnaryOpc_match(unsigned Opc, const Opnd_P &Op,
1084 SDNodeFlags Flgs = SDNodeFlags())
1085 : Opcode(Opc), Opnd(Op), Flags(Flgs) {}
1086
1088 if (sd_match(N, m_SpecificOpc(Opcode))) {
1090 assert(EO.Size == 1);
1091 if (!Opnd.match(N->getOperand(EO.FirstIndex)))
1092 return false;
1093
1094 return (Flags & N->getFlags()) == Flags;
1095 }
1096
1097 return false;
1098 }
1099};
1100
1101template <typename Opnd>
1102inline UnaryOpc_match<Opnd> m_UnaryOp(unsigned Opc, const Opnd &Op) {
1103 return UnaryOpc_match<Opnd>(Opc, Op);
1104}
1105template <typename Opnd>
1107 const Opnd &Op) {
1109}
1110
1111template <typename Opnd> inline UnaryOpc_match<Opnd> m_BitCast(const Opnd &Op) {
1113}
1114
1115template <typename Opnd>
1116inline UnaryOpc_match<Opnd> m_BSwap(const Opnd &Op) {
1118}
1119
1120template <typename Opnd>
1124
1125template <typename Opnd> inline UnaryOpc_match<Opnd> m_ZExt(const Opnd &Op) {
1127}
1128
1129template <typename Opnd>
1133
1134template <typename Opnd> inline auto m_SExt(const Opnd &Op) {
1136}
1137
1138template <typename Opnd> inline UnaryOpc_match<Opnd> m_AnyExt(const Opnd &Op) {
1140}
1141
1142template <typename Opnd> inline UnaryOpc_match<Opnd> m_Trunc(const Opnd &Op) {
1144}
1145
1146template <typename Opnd> inline auto m_Abs(const Opnd &Op) {
1149}
1150
1151template <typename Opnd> inline UnaryOpc_match<Opnd> m_FAbs(const Opnd &Op) {
1153}
1154
1155/// Match a zext or identity
1156/// Allows to peek through optional extensions
1157template <typename Opnd> inline auto m_ZExtOrSelf(const Opnd &Op) {
1158 return m_AnyOf(m_ZExt(Op), Op);
1159}
1160
1161/// Match a sext or identity
1162/// Allows to peek through optional extensions
1163template <typename Opnd> inline auto m_SExtOrSelf(const Opnd &Op) {
1164 return m_AnyOf(m_SExt(Op), Op);
1165}
1166
1167template <typename Opnd> inline auto m_SExtLike(const Opnd &Op) {
1168 return m_AnyOf(m_SExt(Op), m_NNegZExt(Op));
1169}
1170
1171/// Match a aext or identity
1172/// Allows to peek through optional extensions
1173template <typename Opnd>
1174inline Or<UnaryOpc_match<Opnd>, Opnd> m_AExtOrSelf(const Opnd &Op) {
1175 return Or<UnaryOpc_match<Opnd>, Opnd>(m_AnyExt(Op), Op);
1176}
1177
1178/// Match a trunc or identity
1179/// Allows to peek through optional truncations
1180template <typename Opnd>
1181inline Or<UnaryOpc_match<Opnd>, Opnd> m_TruncOrSelf(const Opnd &Op) {
1182 return Or<UnaryOpc_match<Opnd>, Opnd>(m_Trunc(Op), Op);
1183}
1184
1185template <typename Opnd> inline UnaryOpc_match<Opnd> m_VScale(const Opnd &Op) {
1187}
1188
1189template <typename Opnd> inline UnaryOpc_match<Opnd> m_FPToUI(const Opnd &Op) {
1191}
1192
1193template <typename Opnd> inline UnaryOpc_match<Opnd> m_FPToSI(const Opnd &Op) {
1195}
1196
1197template <typename Opnd> inline UnaryOpc_match<Opnd> m_Ctpop(const Opnd &Op) {
1199}
1200
1201template <typename Opnd> inline UnaryOpc_match<Opnd> m_Ctlz(const Opnd &Op) {
1203}
1204
1205template <typename Opnd> inline UnaryOpc_match<Opnd> m_Cttz(const Opnd &Op) {
1207}
1208
1209template <typename Opnd> inline UnaryOpc_match<Opnd> m_FNeg(const Opnd &Op) {
1211}
1212
1213template <typename Opnd>
1217
1218// === Constants ===
1221
1222 explicit ConstantInt_match(APInt *V) : BindVal(V) {}
1223
1225 // The logics here are similar to that in
1226 // SelectionDAG::isConstantIntBuildVectorOrConstantInt, but the latter also
1227 // treats GlobalAddressSDNode as a constant, which is difficult to turn into
1228 // APInt.
1229 if (auto *C = dyn_cast_or_null<ConstantSDNode>(N.getNode())) {
1230 if (BindVal)
1231 *BindVal = C->getAPIntValue();
1232 return true;
1233 }
1234
1235 APInt Discard;
1236 return ISD::isConstantSplatVector(N.getNode(),
1237 BindVal ? *BindVal : Discard);
1238 }
1239};
1240
1241template <typename T> struct Constant64_match {
1242 static_assert(sizeof(T) == 8, "T must be 64 bits wide");
1243
1245
1246 explicit Constant64_match(T &V) : BindVal(V) {}
1247
1249 APInt V;
1250 if (!ConstantInt_match(&V).match(N))
1251 return false;
1252
1253 if constexpr (std::is_signed_v<T>) {
1254 if (std::optional<int64_t> TrySExt = V.trySExtValue()) {
1255 BindVal = *TrySExt;
1256 return true;
1257 }
1258 }
1259
1260 if constexpr (std::is_unsigned_v<T>) {
1261 if (std::optional<uint64_t> TryZExt = V.tryZExtValue()) {
1262 BindVal = *TryZExt;
1263 return true;
1264 }
1265 }
1266
1267 return false;
1268 }
1269};
1270
1271/// Match any integer constants or splat of an integer constant.
1273/// Match any integer constants or splat of an integer constant; return the
1274/// specific constant or constant splat value.
1276/// Match any integer constants or splat of an integer constant that can fit in
1277/// 64 bits; return the specific constant or constant splat value, zero-extended
1278/// to 64 bits.
1282/// Match any integer constants or splat of an integer constant that can fit in
1283/// 64 bits; return the specific constant or constant splat value, sign-extended
1284/// to 64 bits.
1286 return Constant64_match<int64_t>(V);
1287}
1288
1289template <typename T0_P, typename T1_P, typename T2_P, bool Left>
1291 SDValue N, unsigned BitWidth) {
1292 SDValue X, Y, ShlAmt, SrlAmt;
1293 APInt ShlConst, SrlConst;
1294 if (!sd_match(
1295 N, m_Or(m_Shl(m_Value(X), m_Value(ShlAmt, m_ConstInt(ShlConst))),
1296 m_Srl(m_Value(Y), m_Value(SrlAmt, m_ConstInt(SrlConst))))) ||
1297 !hasComplementaryConstantShifts(ShlConst, SrlConst, BitWidth))
1298 return false;
1299
1300 return matchOperands(X, Y, Left ? ShlAmt : SrlAmt);
1301}
1302
1305
1306 explicit SpecificInt_match(APInt APV) : IntVal(std::move(APV)) {}
1307
1309 APInt ConstInt;
1310 if (sd_match(N, m_ConstInt(ConstInt)))
1311 return APInt::isSameValue(IntVal, ConstInt);
1312 return false;
1313 }
1314};
1315
1316/// Match a specific integer constant or constant splat value.
1318 return SpecificInt_match(std::move(V));
1319}
1321 return SpecificInt_match(APInt(64, V));
1322}
1323
1326
1327 explicit SpecificFP_match(APFloat V) : Val(V) {}
1328
1329 bool match(SDValue V) {
1330 if (const auto *CFP = dyn_cast<ConstantFPSDNode>(V.getNode()))
1331 return CFP->isExactlyValue(Val);
1332 if (ConstantFPSDNode *C = isConstOrConstSplatFP(V, /*AllowUndefs=*/true))
1333 return C->getValueAPF().compare(Val) == APFloat::cmpEqual;
1334 return false;
1335 }
1336};
1337
1338/// Match a specific float constant.
1340
1342 return SpecificFP_match(APFloat(V));
1343}
1344
1348 return C->isZero();
1349 return false;
1350 }
1351};
1352
1353/// Match a floating-point +0.0 or -0.0 constant or splat.
1355
1358
1360
1361 bool match(SDValue N) const { return isZeroOrZeroSplat(N, AllowUndefs); }
1362};
1363
1371
1379
1380inline Ones_match m_One(bool AllowUndefs = false) {
1381 return Ones_match(AllowUndefs);
1382}
1383inline Zero_match m_Zero(bool AllowUndefs = false) {
1384 return Zero_match(AllowUndefs);
1385}
1386inline AllOnes_match m_AllOnes(bool AllowUndefs = false) {
1387 return AllOnes_match(AllowUndefs);
1388}
1389
1390template <bool Expected> struct Bool_match {
1392
1394
1396 auto Res = DAG.isBoolConstant(N);
1397 return Res && *Res == Expected;
1398 }
1399};
1400
1401/// Match true boolean value based on the information provided by
1402/// TargetLowering.
1403inline auto m_True(const SelectionDAG &DAG) { return Bool_match<true>(DAG); }
1404
1405/// Match false boolean value based on the information provided by
1406/// TargetLowering.
1407inline auto m_False(const SelectionDAG &DAG) { return Bool_match<false>(DAG); }
1408
1409/// Match a negate as a sub(0, v)
1410template <typename ValTy>
1412 return m_Sub(m_Zero(), V);
1413}
1414
1415/// Match a Not as a xor(v, -1) or xor(-1, v)
1416template <typename ValTy>
1418 return m_Xor(V, m_AllOnes());
1419}
1420
1421template <unsigned IntrinsicId, typename... OpndPreds>
1422inline auto m_IntrinsicWOChain(const OpndPreds &...Opnds) {
1423 return m_Node(ISD::INTRINSIC_WO_CHAIN, m_SpecificInt(IntrinsicId), Opnds...);
1424}
1425
1428
1430
1432 if (sd_match(N, m_Neg(m_Specific(V))))
1433 return true;
1434
1437 return LHS->getAPIntValue() == -RHS->getAPIntValue();
1438 });
1439 }
1440};
1441
1442/// Match a negation of a specific value V, either as sub(0, V) or as
1443/// constant(s) that are the negation of V's constant(s).
1447
1448template <typename... PatternTs> struct ReassociatableOpc_match {
1449 unsigned Opcode;
1450 std::tuple<PatternTs...> Patterns;
1451 constexpr static size_t NumPatterns =
1452 std::tuple_size_v<std::tuple<PatternTs...>>;
1453
1455
1456 ReassociatableOpc_match(unsigned Opcode, const PatternTs &...Patterns)
1457 : Opcode(Opcode), Patterns(Patterns...) {}
1458
1460 const PatternTs &...Patterns)
1462
1464 std::array<SDValue, NumPatterns> Leaves;
1465 size_t LeavesIdx = 0;
1466 if (!(collectLeaves(N, Leaves, LeavesIdx) && (LeavesIdx == NumPatterns)))
1467 return false;
1468
1470 return std::apply(
1471 [&](auto &...P) -> bool {
1472 return reassociatableMatchHelper(Leaves, Used, P...);
1473 },
1474 Patterns);
1475 }
1476
1477 bool collectLeaves(SDValue V, std::array<SDValue, NumPatterns> &Leaves,
1478 std::size_t &LeafIdx) {
1479 if (V->getOpcode() == Opcode && (Flags & V->getFlags()) == Flags) {
1480 for (size_t I = 0, N = V->getNumOperands(); I < N; I++)
1481 if ((LeafIdx == NumPatterns) ||
1482 !collectLeaves(V->getOperand(I), Leaves, LeafIdx))
1483 return false;
1484 } else {
1485 Leaves[LeafIdx] = V;
1486 LeafIdx++;
1487 }
1488 return true;
1489 }
1490
1491 // Searchs for a matching leaf for every sub-pattern.
1492 template <typename PatternHd, typename... PatternTl>
1493 [[nodiscard]] inline bool
1495 PatternHd &HeadPattern,
1496 PatternTl &...TailPatterns) {
1497 for (size_t Match = 0, N = Used.size(); Match < N; Match++) {
1498 if (Used[Match] || !(sd_match(Leaves[Match], HeadPattern)))
1499 continue;
1500 Used.set(Match);
1501 if (reassociatableMatchHelper(Leaves, Used, TailPatterns...))
1502 return true;
1503 Used.reset(Match);
1504 }
1505 return false;
1506 }
1507
1508 [[nodiscard]] inline bool
1510 Bitset<NumPatterns> &Used) {
1511 return true;
1512 }
1513};
1514
1515template <typename... PatternTs>
1516inline ReassociatableOpc_match<PatternTs...>
1517m_ReassociatableAdd(const PatternTs &...Patterns) {
1518 return ReassociatableOpc_match<PatternTs...>(ISD::ADD, Patterns...);
1519}
1520
1521template <typename... PatternTs>
1522inline ReassociatableOpc_match<PatternTs...>
1523m_ReassociatableOr(const PatternTs &...Patterns) {
1524 return ReassociatableOpc_match<PatternTs...>(ISD::OR, Patterns...);
1525}
1526
1527template <typename... PatternTs>
1528inline ReassociatableOpc_match<PatternTs...>
1529m_ReassociatableAnd(const PatternTs &...Patterns) {
1530 return ReassociatableOpc_match<PatternTs...>(ISD::AND, Patterns...);
1531}
1532
1533template <typename... PatternTs>
1534inline ReassociatableOpc_match<PatternTs...>
1535m_ReassociatableMul(const PatternTs &...Patterns) {
1536 return ReassociatableOpc_match<PatternTs...>(ISD::MUL, Patterns...);
1537}
1538
1539template <typename... PatternTs>
1540inline ReassociatableOpc_match<PatternTs...>
1541m_ReassociatableNSWAdd(const PatternTs &...Patterns) {
1542 return ReassociatableOpc_match<PatternTs...>(
1543 ISD::ADD, SDNodeFlags::NoSignedWrap, Patterns...);
1544}
1545
1546template <typename... PatternTs>
1547inline ReassociatableOpc_match<PatternTs...>
1548m_ReassociatableNUWAdd(const PatternTs &...Patterns) {
1549 return ReassociatableOpc_match<PatternTs...>(
1551}
1552
1553} // namespace SDPatternMatch
1554} // namespace llvm
1555#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file implements a class to represent arbitrary precision integral constant values and operations...
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static constexpr unsigned long long mask(BlockVerifier::State S)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
#define T1
#define P(N)
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
This file implements the C++20 <bit> header.
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static bool isSameValue(const APInt &I1, const APInt &I2, bool SignedCompare=false)
Determine if two APInts have the same value, after zero-extending or sign-extending (if SignedCompare...
Definition APInt.h:550
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This is a constexpr reimplementation of a subset of std::bitset.
Definition Bitset.h:30
Tagged union holding either a T or a Error.
Definition Error.h:485
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const TargetLowering & getTargetLoweringInfo() const
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:837
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:238
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition ISDOpcodes.h:605
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:797
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:871
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:757
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:788
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:862
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:814
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:235
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:779
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:659
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:619
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:581
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:868
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:829
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:737
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
Definition ISDOpcodes.h:650
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:823
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:944
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:749
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:207
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
Definition ISDOpcodes.h:667
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:570
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:874
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
Definition ISDOpcodes.h:761
LLVM_ABI bool matchBinaryPredicate(SDValue LHS, SDValue RHS, const APInt &DemandedElts, std::function< bool(ConstantSDNode *, ConstantSDNode *)> Match, bool AllowUndefs=false, bool AllowTypeMismatch=false)
Attempt to match a binary predicate against a pair of scalar/splat constants or every element of a pa...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
AllOnesConstantMatch m_AllOnes()
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_VScale()
Matches a call to llvm.vscale().
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOpc_match< Zero_match, ValTy, false > m_Neg(const ValTy &V)
Match a negate as a sub(0, v)
Result_match< 0, TernaryOpc_match< T0_P, T1_P, T2_P > > m_Load(const T0_P &Ch, const T1_P &Ptr, const T2_P &Offset)
ReassociatableOpc_match< PatternTs... > m_ReassociatableMul(const PatternTs &...Patterns)
auto m_ExactSr(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_Srl(const LHS &L, const RHS &R)
auto m_SExtLike(const Opnd &Op)
auto m_SpecificVT(EVT RefVT, const Pattern &P)
Match a specific ValueType.
Opcode_match m_SpecificOpc(unsigned Opcode)
BinaryOpc_match< LHS, RHS > m_Sra(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_FRem(const LHS &L, const RHS &R)
auto m_False(const SelectionDAG &DAG)
Match false boolean value based on the information provided by TargetLowering.
TLI_pred_match(const PredFuncT &Pred, const Pattern &P) -> TLI_pred_match< Pattern, PredFuncT >
TernaryOpc_match< T0_P, T1_P, CondCode_match, true, false > m_c_SetCC(const T0_P &LHS, const T1_P &RHS)
Match a SETCC with any condition code, allowing the operands to be commuted.
auto m_Abs(const Opnd &Op)
Result_match< ResNo, Pattern > m_Result(const Pattern &P)
Match only if the SDValue is a certain result at ResNo.
auto m_MaxMinLike(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_c_BinOp(unsigned Opc, const LHS &L, const RHS &R, SDNodeFlags Flgs=SDNodeFlags())
BinaryOpc_match< LHS, RHS, true > m_Mul(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_Clmul(const LHS &L, const RHS &R)
auto m_UMinLike(const LHS &L, const RHS &R)
auto m_SelectCC(const LTy &L, const RTy &R, const TTy &T, const FTy &F)
Match a SELECT_CC with any condition code.
auto m_SelectLike(const T0_P &Cond, const T1_P &T, const T2_P &F)
TernaryOpc_match< LHS, RHS, IDX > m_InsertSubvector(const LHS &Base, const RHS &Sub, const IDX &Idx)
auto m_UMaxLike(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_Or(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, T2_P > m_TernaryOp(unsigned Opc, const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
TernaryOpc_match< T0_P, T1_P, T2_P > m_InsertElt(const T0_P &Vec, const T1_P &Val, const T2_P &Idx)
BinaryOpc_match< LHS, RHS, false, true > m_ChainedBinOp(unsigned Opc, const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_SMin(const LHS &L, const RHS &R)
auto m_IntrinsicWOChain(const OpndPreds &...Opnds)
UnaryOpc_match< Opnd > m_Trunc(const Opnd &Op)
BinaryOpc_match< LHS, RHS > m_FSub(const LHS &L, const RHS &R)
auto m_AddLike(const LHS &L, const RHS &R)
auto m_SpecificSelectCCLike(ISD::CondCode CC, const LTy &L, const RTy &R, const TTy &T, const FTy &F)
Match a SELECT of a SETCC or a SELECT_CC with a specific condition code.
BinaryOpc_match< LHS, RHS > m_URem(const LHS &L, const RHS &R)
AnyZeroFP_match m_AnyZeroFP()
Match a floating-point +0.0 or -0.0 constant or splat.
UnaryOpc_match< Opnd > m_BSwap(const Opnd &Op)
Or< Preds... > m_AnyOf(const Preds &...preds)
BinaryOpc_match< LHS, RHS, true, true > m_c_ChainedBinOp(unsigned Opc, const LHS &L, const RHS &R)
Or< UnaryOpc_match< Opnd >, Opnd > m_TruncOrSelf(const Opnd &Op)
Match a trunc or identity Allows to peek through optional truncations.
UnaryOpc_match< Opnd > m_NNegZExt(const Opnd &Op)
TernaryOpc_match< T0_P, T1_P, T2_P > m_FShR(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
And< Preds... > m_AllOf(const Preds &...preds)
UnaryOpc_match< Opnd > m_VectorReverse(const Opnd &Op)
BinaryOpc_match< LHS, RHS > m_FDiv(const LHS &L, const RHS &R)
auto m_NSWAdd(const LHS &L, const RHS &R)
UnaryOpc_match< Opnd > m_BitCast(const Opnd &Op)
UnaryOpc_match< Opnd > m_FNeg(const Opnd &Op)
FunnelShiftLike_match< T0_P, T1_P, T2_P, false > m_FShRLike(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
Opcode_match m_Poison()
auto m_LegalType(const SelectionDAG &DAG, const Pattern &P)
Match legal ValueTypes based on the information provided by TargetLowering.
BinaryOpc_match< LHS, RHS, true > m_UMin(const LHS &L, const RHS &R)
Not< Pred > m_Unless(const Pred &P)
Match if the inner pattern does NOT match.
BinaryOpc_match< LHS, RHS, true > m_SMax(const LHS &L, const RHS &R)
auto m_SpecificScalarVT(EVT RefVT, const Pattern &P)
Match a scalar ValueType.
auto m_True(const SelectionDAG &DAG)
Match true boolean value based on the information provided by TargetLowering.
NUses_match< N, Value_match > m_NUses()
UnaryOpc_match< Opnd, true > m_ChainedUnaryOp(unsigned Opc, const Opnd &Op)
ValueType_match(const PredFuncT &Pred, const Pattern &P) -> ValueType_match< Pattern, PredFuncT >
SpecificInt_match m_SpecificInt(APInt V)
Match a specific integer constant or constant splat value.
UnaryOpc_match< Opnd > m_FPToUI(const Opnd &Op)
auto m_NUWAddLike(const LHS &L, const RHS &R)
SpecificFP_match m_SpecificFP(APFloat V)
Match a specific float constant.
Value_match m_Specific(SDValue N)
BinaryOpc_match< LHS, RHS > m_ExtractElt(const LHS &Vec, const RHS &Idx)
BinaryOpc_match< LHS, RHS > m_ExtractSubvector(const LHS &Vec, const RHS &Idx)
UnaryOpc_match< Opnd > m_BitReverse(const Opnd &Op)
BinaryOpc_match< LHS, RHS, true > m_And(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_Sub(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, CondCode_match > m_SpecificSetCC(ISD::CondCode CC, const T0_P &LHS, const T1_P &RHS)
Match a SETCC with a specific condition code.
TernaryOpc_match< T0_P, T1_P, T2_P, true > m_c_TernaryOp(unsigned Opc, const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
ReassociatableOpc_match< PatternTs... > m_ReassociatableNUWAdd(const PatternTs &...Patterns)
auto m_NSWAddLike(const LHS &L, const RHS &R)
auto m_VT(EVT &VT)
Retreive the ValueType of the current SDValue.
BinaryOpc_match< ValTy, AllOnes_match, true > m_Not(const ValTy &V)
Match a Not as a xor(v, -1) or xor(-1, v)
ReassociatableOpc_match< PatternTs... > m_ReassociatableOr(const PatternTs &...Patterns)
BinaryOpc_match< LHS, RHS > m_Rotr(const LHS &L, const RHS &R)
ReassociatableOpc_match< PatternTs... > m_ReassociatableAdd(const PatternTs &...Patterns)
UnaryOpc_match< Opnd > m_AnyExt(const Opnd &Op)
BinaryOpc_match< LHS, RHS > m_Rotl(const LHS &L, const RHS &R)
UnaryOpc_match< Opnd > m_Cttz(const Opnd &Op)
auto m_SelectCCLike(const LTy &L, const RTy &R, const TTy &T, const FTy &F)
Match a SELECT of a SETCC or a SELECT_CC with any condition code.
TernaryOpc_match< T0_P, T1_P, CondCode_match, true, false > m_c_SpecificSetCC(ISD::CondCode CC, const T0_P &LHS, const T1_P &RHS)
Match a SETCC with a specific condition code, allowing the operands to be commuted.
auto m_Node(unsigned Opcode, const OpndPreds &...preds)
BinaryOpc_match< LHS, RHS, true > m_DisjointOr(const LHS &L, const RHS &R)
auto m_SMaxLike(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, T2_P > m_Select(const T0_P &Cond, const T1_P &T, const T2_P &F)
BinaryOpc_match< LHS, RHS > m_UDiv(const LHS &L, const RHS &R)
UnaryOpc_match< Opnd > m_Ctlz(const Opnd &Op)
SpecificNeg_match m_SpecificNeg(SDValue V)
Match a negation of a specific value V, either as sub(0, V) or as constant(s) that are the negation o...
BinaryOpc_match< LHS, RHS > m_SDiv(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_FAdd(const LHS &L, const RHS &R)
Or< UnaryOpc_match< Opnd >, Opnd > m_AExtOrSelf(const Opnd &Op)
Match a aext or identity Allows to peek through optional extensions.
BinaryOpc_match< LHS, RHS, true > m_UMax(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, T2_P > m_VSelect(const T0_P &Cond, const T1_P &T, const T2_P &F)
TernaryOpc_match< T0_P, T1_P, T2_P > m_FShL(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
UnaryOpc_match< Opnd > m_UnaryOp(unsigned Opc, const Opnd &Op)
auto m_SExt(const Opnd &Op)
bool sd_match(SDValue N, Pattern &&P)
ReassociatableOpc_match< PatternTs... > m_ReassociatableNSWAdd(const PatternTs &...Patterns)
BinaryOpc_match< LHS, RHS, true > m_Xor(const LHS &L, const RHS &R)
auto m_SMinLike(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_SRem(const LHS &L, const RHS &R)
auto m_NoneOf(const Preds &...preds)
CondCode_match m_SpecificCondCode(ISD::CondCode CC)
Match a conditional code SDNode with a specific ISD::CondCode.
UnaryOpc_match< Opnd > m_ZExt(const Opnd &Op)
Value_match m_Value()
Match any valid SDValue.
BinaryOpc_match< LHS, RHS, true > m_Add(const LHS &L, const RHS &R)
auto m_SpecificVectorElementVT(EVT RefVT, const Pattern &P)
Match a vector ValueType.
BinaryOpc_match< LHS, RHS > m_Shl(const LHS &L, const RHS &R)
auto m_BitwiseLogic(const LHS &L, const RHS &R)
UnaryOpc_match< Opnd > m_Ctpop(const Opnd &Op)
auto m_LegalOp(const SelectionDAG &DAG, const Pattern &P)
Match legal SDNodes based on the information provided by TargetLowering.
TernaryOpc_match< T0_P, T1_P, CondCode_match > m_SetCC(const T0_P &LHS, const T1_P &RHS)
Match a SETCC with any condition code.
ReassociatableOpc_match< PatternTs... > m_ReassociatableAnd(const PatternTs &...Patterns)
TernaryOpc_match< T0_P, T1_P, T2_P > m_SpliceRight(const T0_P &V1, const T1_P &V2, const T2_P &Offset)
UnaryOpc_match< Opnd > m_FPToSI(const Opnd &Op)
NUses_match< 1, Value_match > m_OneUse()
auto m_NUWAdd(const LHS &L, const RHS &R)
auto m_SExtOrSelf(const Opnd &Op)
Match a sext or identity Allows to peek through optional extensions.
CondCode_match m_CondCode()
Match any conditional code SDNode.
UnaryOpc_match< Opnd > m_FAbs(const Opnd &Op)
Not(const Pred &P) -> Not< Pred >
DeferredValue_match m_Deferred(SDValue &V)
Similar to m_Specific, but the specific value to match is determined by another sub-pattern in the sa...
BinaryOpc_match< LHS, RHS, true > m_FMul(const LHS &L, const RHS &R)
BinaryOpc_match< V1_t, V2_t > m_Shuffle(const V1_t &v1, const V2_t &v2)
auto m_SpecificSelectCC(ISD::CondCode CC, const LTy &L, const RTy &R, const TTy &T, const FTy &F)
Match a SELECT_CC with a specific condition code.
ValueType_bind(const Pattern &P) -> ValueType_bind< Pattern >
ConstantInt_match m_ConstInt()
Match any integer constants or splat of an integer constant.
FunnelShiftLike_match< T0_P, T1_P, T2_P, true > m_FShLLike(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
auto m_ZExtOrSelf(const Opnd &Op)
Match a zext or identity Allows to peek through optional extensions.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI bool isAllOnesOrAllOnesSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant -1 integer or a splatted vector of a constant -1 integer (with...
Definition Utils.cpp:1557
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:325
LLVM_ABI ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isZeroOrZeroSplat(SDValue N, bool AllowUndefs=false)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
LLVM_ABI bool isOnesOrOnesSplat(SDValue N, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
Extended Value Type.
Definition ValueTypes.h:35
These are IR-level optimization flags that may be propagated to SDNodes.
And(const Pred &p, const Preds &...preds)
BinaryOpc_match(unsigned Opc, const LHS_P &L, const RHS_P &R, SDNodeFlags Flgs=SDNodeFlags())
Bool_match(const SelectionDAG &DAG)
std::optional< ISD::CondCode > CCToMatch
Provide number of operands that are not chain or glue, as well as the first index of such operand.
bool matchShiftOr(SDValue N, unsigned BitWidth)
bool matchOperands(SDValue X, SDValue Y, SDValue Z)
static bool hasComplementaryConstantShifts(const APInt &ShlV, const APInt &SrlV, unsigned BitWidth)
FunnelShiftLike_match(const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
MaxMin_match(const LHS_P &L, const RHS_P &R)
Operands_match(const OpndPred &p, const OpndPreds &...preds)
Or(const Pred &p, const Preds &...preds)
bool reassociatableMatchHelper(ArrayRef< SDValue > Leaves, Bitset< NumPatterns > &Used)
bool reassociatableMatchHelper(ArrayRef< SDValue > Leaves, Bitset< NumPatterns > &Used, PatternHd &HeadPattern, PatternTl &...TailPatterns)
bool collectLeaves(SDValue V, std::array< SDValue, NumPatterns > &Leaves, std::size_t &LeafIdx)
ReassociatableOpc_match(unsigned Opcode, const PatternTs &...Patterns)
ReassociatableOpc_match(unsigned Opcode, SDNodeFlags Flags, const PatternTs &...Patterns)
Matching while capturing mask.
SDShuffle_match(const T0 &Op1, const T1 &Op2, const T2 &Mask)
TLI_pred_match(const PredFuncT &Pred, const Pattern &P)
TernaryOpc_match(unsigned Opc, const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
UnaryOpc_match(unsigned Opc, const Opnd_P &Op, SDNodeFlags Flgs=SDNodeFlags())
ValueType_bind(EVT &Bind, const Pattern &P)
ValueType_match(const PredFuncT &Pred, const Pattern &P)
bool match(ArrayRef< int > Mask)
m_Mask(ArrayRef< int > &MaskRef)
m_SpecificMask(ArrayRef< int > MaskRef)
bool match(ArrayRef< int > Mask)
static bool match(ISD::CondCode Cond)
static bool match(ISD::CondCode Cond)
static bool match(ISD::CondCode Cond)
static bool match(ISD::CondCode Cond)