LLVM 22.0.0git
PatternMatch.h
Go to the documentation of this file.
1//===- PatternMatch.h - Match on the LLVM IR --------------------*- 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//
9// This file provides a simple and efficient mechanism for performing general
10// tree-based pattern matches on the LLVM IR. The power of these routines is
11// that it allows you to write concise patterns that are expressive and easy to
12// understand. The other major advantage of this is that it allows you to
13// trivially capture/bind elements in the pattern to variables. For example,
14// you can do something like this:
15//
16// Value *Exp = ...
17// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
18// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
19// m_And(m_Value(Y), m_ConstantInt(C2))))) {
20// ... Pattern is matched and variables are bound ...
21// }
22//
23// This is primarily useful to things like the instruction combiner, but can
24// also be useful for static analysis tools or code generators.
25//
26//===----------------------------------------------------------------------===//
27
28#ifndef LLVM_IR_PATTERNMATCH_H
29#define LLVM_IR_PATTERNMATCH_H
30
31#include "llvm/ADT/APFloat.h"
32#include "llvm/ADT/APInt.h"
33#include "llvm/IR/Constant.h"
34#include "llvm/IR/Constants.h"
35#include "llvm/IR/DataLayout.h"
36#include "llvm/IR/InstrTypes.h"
37#include "llvm/IR/Instruction.h"
40#include "llvm/IR/Intrinsics.h"
41#include "llvm/IR/Operator.h"
42#include "llvm/IR/Value.h"
44#include <cstdint>
45
46namespace llvm {
47namespace PatternMatch {
48
49template <typename Val, typename Pattern> bool match(Val *V, const Pattern &P) {
50 return P.match(V);
51}
52
53template <typename Val, typename Pattern> struct MatchFunctor {
54 const Pattern &P;
55 MatchFunctor(const Pattern &P) : P(P) {}
56 bool operator()(Val *V) const { return P.match(V); }
57};
58
59/// A match functor that can be used as a UnaryPredicate in functional
60/// algorithms like all_of.
61template <typename Val = const Value, typename Pattern>
65
66template <typename Pattern> bool match(ArrayRef<int> Mask, const Pattern &P) {
67 return P.match(Mask);
68}
69
70template <typename SubPattern_t> struct OneUse_match {
71 SubPattern_t SubPattern;
72
73 OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {}
74
75 template <typename OpTy> bool match(OpTy *V) const {
76 return V->hasOneUse() && SubPattern.match(V);
77 }
78};
79
80template <typename T> inline OneUse_match<T> m_OneUse(const T &SubPattern) {
81 return SubPattern;
82}
83
84template <typename SubPattern_t> struct AllowReassoc_match {
85 SubPattern_t SubPattern;
86
87 AllowReassoc_match(const SubPattern_t &SP) : SubPattern(SP) {}
88
89 template <typename OpTy> bool match(OpTy *V) const {
90 auto *I = dyn_cast<FPMathOperator>(V);
91 return I && I->hasAllowReassoc() && SubPattern.match(I);
92 }
93};
94
95template <typename T>
96inline AllowReassoc_match<T> m_AllowReassoc(const T &SubPattern) {
97 return SubPattern;
98}
99
100template <typename Class> struct class_match {
101 template <typename ITy> bool match(ITy *V) const { return isa<Class>(V); }
102};
103
104/// Match an arbitrary value and ignore it.
106
107/// Match an arbitrary unary operation and ignore it.
111
112/// Match an arbitrary binary operation and ignore it.
116
117/// Matches any compare instruction and ignore it.
119
121 static bool check(const Value *V) {
122 if (isa<UndefValue>(V))
123 return true;
124
125 const auto *CA = dyn_cast<ConstantAggregate>(V);
126 if (!CA)
127 return false;
128
131
132 // Either UndefValue, PoisonValue, or an aggregate that only contains
133 // these is accepted by matcher.
134 // CheckValue returns false if CA cannot satisfy this constraint.
135 auto CheckValue = [&](const ConstantAggregate *CA) {
136 for (const Value *Op : CA->operand_values()) {
137 if (isa<UndefValue>(Op))
138 continue;
139
140 const auto *CA = dyn_cast<ConstantAggregate>(Op);
141 if (!CA)
142 return false;
143 if (Seen.insert(CA).second)
144 Worklist.emplace_back(CA);
145 }
146
147 return true;
148 };
149
150 if (!CheckValue(CA))
151 return false;
152
153 while (!Worklist.empty()) {
154 if (!CheckValue(Worklist.pop_back_val()))
155 return false;
156 }
157 return true;
158 }
159 template <typename ITy> bool match(ITy *V) const { return check(V); }
160};
161
162/// Match an arbitrary undef constant. This matches poison as well.
163/// If this is an aggregate and contains a non-aggregate element that is
164/// neither undef nor poison, the aggregate is not matched.
165inline auto m_Undef() { return undef_match(); }
166
167/// Match an arbitrary UndefValue constant.
171
172/// Match an arbitrary poison constant.
176
177/// Match an arbitrary Constant and ignore it.
179
180/// Match an arbitrary ConstantInt and ignore it.
184
185/// Match an arbitrary ConstantFP and ignore it.
189
191 template <typename ITy> bool match(ITy *V) const {
192 auto *C = dyn_cast<Constant>(V);
193 return C && (isa<ConstantExpr>(C) || C->containsConstantExpression());
194 }
195};
196
197/// Match a constant expression or a constant that contains a constant
198/// expression.
200
201template <typename SubPattern_t> struct Splat_match {
202 SubPattern_t SubPattern;
203 Splat_match(const SubPattern_t &SP) : SubPattern(SP) {}
204
205 template <typename OpTy> bool match(OpTy *V) const {
206 if (auto *C = dyn_cast<Constant>(V)) {
207 auto *Splat = C->getSplatValue();
208 return Splat ? SubPattern.match(Splat) : false;
209 }
210 // TODO: Extend to other cases (e.g. shufflevectors).
211 return false;
212 }
213};
214
215/// Match a constant splat. TODO: Extend this to non-constant splats.
216template <typename T>
217inline Splat_match<T> m_ConstantSplat(const T &SubPattern) {
218 return SubPattern;
219}
220
221/// Match an arbitrary basic block value and ignore it.
225
226/// Inverting matcher
227template <typename Ty> struct match_unless {
228 Ty M;
229
230 match_unless(const Ty &Matcher) : M(Matcher) {}
231
232 template <typename ITy> bool match(ITy *V) const { return !M.match(V); }
233};
234
235/// Match if the inner matcher does *NOT* match.
236template <typename Ty> inline match_unless<Ty> m_Unless(const Ty &M) {
237 return match_unless<Ty>(M);
238}
239
240/// Matching combinators
241template <typename LTy, typename RTy> struct match_combine_or {
242 LTy L;
243 RTy R;
244
245 match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) {}
246
247 template <typename ITy> bool match(ITy *V) const {
248 if (L.match(V))
249 return true;
250 if (R.match(V))
251 return true;
252 return false;
253 }
254};
255
256template <typename LTy, typename RTy> struct match_combine_and {
257 LTy L;
258 RTy R;
259
260 match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) {}
261
262 template <typename ITy> bool match(ITy *V) const {
263 if (L.match(V))
264 if (R.match(V))
265 return true;
266 return false;
267 }
268};
269
270/// Combine two pattern matchers matching L || R
271template <typename LTy, typename RTy>
272inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) {
273 return match_combine_or<LTy, RTy>(L, R);
274}
275
276/// Combine two pattern matchers matching L && R
277template <typename LTy, typename RTy>
278inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) {
279 return match_combine_and<LTy, RTy>(L, R);
280}
281
282template <typename APTy> struct ap_match {
283 static_assert(std::is_same_v<APTy, APInt> || std::is_same_v<APTy, APFloat>);
285 std::conditional_t<std::is_same_v<APTy, APInt>, ConstantInt, ConstantFP>;
286
287 const APTy *&Res;
289
290 ap_match(const APTy *&Res, bool AllowPoison)
292
293 template <typename ITy> bool match(ITy *V) const {
294 if (auto *CI = dyn_cast<ConstantTy>(V)) {
295 Res = &CI->getValue();
296 return true;
297 }
298 if (V->getType()->isVectorTy())
299 if (const auto *C = dyn_cast<Constant>(V))
300 if (auto *CI =
301 dyn_cast_or_null<ConstantTy>(C->getSplatValue(AllowPoison))) {
302 Res = &CI->getValue();
303 return true;
304 }
305 return false;
306 }
307};
308
309/// Match a ConstantInt or splatted ConstantVector, binding the
310/// specified pointer to the contained APInt.
311inline ap_match<APInt> m_APInt(const APInt *&Res) {
312 // Forbid poison by default to maintain previous behavior.
313 return ap_match<APInt>(Res, /* AllowPoison */ false);
314}
315
316/// Match APInt while allowing poison in splat vector constants.
318 return ap_match<APInt>(Res, /* AllowPoison */ true);
319}
320
321/// Match APInt while forbidding poison in splat vector constants.
323 return ap_match<APInt>(Res, /* AllowPoison */ false);
324}
325
326/// Match a ConstantFP or splatted ConstantVector, binding the
327/// specified pointer to the contained APFloat.
329 // Forbid undefs by default to maintain previous behavior.
330 return ap_match<APFloat>(Res, /* AllowPoison */ false);
331}
332
333/// Match APFloat while allowing poison in splat vector constants.
335 return ap_match<APFloat>(Res, /* AllowPoison */ true);
336}
337
338/// Match APFloat while forbidding poison in splat vector constants.
340 return ap_match<APFloat>(Res, /* AllowPoison */ false);
341}
342
343template <int64_t Val> struct constantint_match {
344 template <typename ITy> bool match(ITy *V) const {
345 if (const auto *CI = dyn_cast<ConstantInt>(V)) {
346 const APInt &CIV = CI->getValue();
347 if (Val >= 0)
348 return CIV == static_cast<uint64_t>(Val);
349 // If Val is negative, and CI is shorter than it, truncate to the right
350 // number of bits. If it is larger, then we have to sign extend. Just
351 // compare their negated values.
352 return -CIV == -Val;
353 }
354 return false;
355 }
356};
357
358/// Match a ConstantInt with a specific value.
359template <int64_t Val> inline constantint_match<Val> m_ConstantInt() {
360 return constantint_match<Val>();
361}
362
363/// This helper class is used to match constant scalars, vector splats,
364/// and fixed width vectors that satisfy a specified predicate.
365/// For fixed width vector constants, poison elements are ignored if AllowPoison
366/// is true.
367template <typename Predicate, typename ConstantVal, bool AllowPoison>
368struct cstval_pred_ty : public Predicate {
369 const Constant **Res = nullptr;
370 template <typename ITy> bool match_impl(ITy *V) const {
371 if (const auto *CV = dyn_cast<ConstantVal>(V))
372 return this->isValue(CV->getValue());
373 if (const auto *VTy = dyn_cast<VectorType>(V->getType())) {
374 if (const auto *C = dyn_cast<Constant>(V)) {
375 if (const auto *CV = dyn_cast_or_null<ConstantVal>(C->getSplatValue()))
376 return this->isValue(CV->getValue());
377
378 // Number of elements of a scalable vector unknown at compile time
379 auto *FVTy = dyn_cast<FixedVectorType>(VTy);
380 if (!FVTy)
381 return false;
382
383 // Non-splat vector constant: check each element for a match.
384 unsigned NumElts = FVTy->getNumElements();
385 assert(NumElts != 0 && "Constant vector with no elements?");
386 bool HasNonPoisonElements = false;
387 for (unsigned i = 0; i != NumElts; ++i) {
388 Constant *Elt = C->getAggregateElement(i);
389 if (!Elt)
390 return false;
391 if (AllowPoison && isa<PoisonValue>(Elt))
392 continue;
393 auto *CV = dyn_cast<ConstantVal>(Elt);
394 if (!CV || !this->isValue(CV->getValue()))
395 return false;
396 HasNonPoisonElements = true;
397 }
398 return HasNonPoisonElements;
399 }
400 }
401 return false;
402 }
403
404 template <typename ITy> bool match(ITy *V) const {
405 if (this->match_impl(V)) {
406 if (Res)
407 *Res = cast<Constant>(V);
408 return true;
409 }
410 return false;
411 }
412};
413
414/// specialization of cstval_pred_ty for ConstantInt
415template <typename Predicate, bool AllowPoison = true>
417
418/// specialization of cstval_pred_ty for ConstantFP
419template <typename Predicate>
421 /*AllowPoison=*/true>;
422
423/// This helper class is used to match scalar and vector constants that
424/// satisfy a specified predicate, and bind them to an APInt.
425template <typename Predicate> struct api_pred_ty : public Predicate {
426 const APInt *&Res;
427
428 api_pred_ty(const APInt *&R) : Res(R) {}
429
430 template <typename ITy> bool match(ITy *V) const {
431 if (const auto *CI = dyn_cast<ConstantInt>(V))
432 if (this->isValue(CI->getValue())) {
433 Res = &CI->getValue();
434 return true;
435 }
436 if (V->getType()->isVectorTy())
437 if (const auto *C = dyn_cast<Constant>(V))
438 if (auto *CI = dyn_cast_or_null<ConstantInt>(
439 C->getSplatValue(/*AllowPoison=*/true)))
440 if (this->isValue(CI->getValue())) {
441 Res = &CI->getValue();
442 return true;
443 }
444
445 return false;
446 }
447};
448
449/// This helper class is used to match scalar and vector constants that
450/// satisfy a specified predicate, and bind them to an APFloat.
451/// Poison is allowed in splat vector constants.
452template <typename Predicate> struct apf_pred_ty : public Predicate {
453 const APFloat *&Res;
454
455 apf_pred_ty(const APFloat *&R) : Res(R) {}
456
457 template <typename ITy> bool match(ITy *V) const {
458 if (const auto *CI = dyn_cast<ConstantFP>(V))
459 if (this->isValue(CI->getValue())) {
460 Res = &CI->getValue();
461 return true;
462 }
463 if (V->getType()->isVectorTy())
464 if (const auto *C = dyn_cast<Constant>(V))
465 if (auto *CI = dyn_cast_or_null<ConstantFP>(
466 C->getSplatValue(/* AllowPoison */ true)))
467 if (this->isValue(CI->getValue())) {
468 Res = &CI->getValue();
469 return true;
470 }
471
472 return false;
473 }
474};
475
476///////////////////////////////////////////////////////////////////////////////
477//
478// Encapsulate constant value queries for use in templated predicate matchers.
479// This allows checking if constants match using compound predicates and works
480// with vector constants, possibly with relaxed constraints. For example, ignore
481// undef values.
482//
483///////////////////////////////////////////////////////////////////////////////
484
485template <typename APTy> struct custom_checkfn {
486 function_ref<bool(const APTy &)> CheckFn;
487 bool isValue(const APTy &C) const { return CheckFn(C); }
488};
489
490/// Match an integer or vector where CheckFn(ele) for each element is true.
491/// For vectors, poison elements are assumed to match.
493m_CheckedInt(function_ref<bool(const APInt &)> CheckFn) {
494 return cst_pred_ty<custom_checkfn<APInt>>{{CheckFn}};
495}
496
498m_CheckedInt(const Constant *&V, function_ref<bool(const APInt &)> CheckFn) {
499 return cst_pred_ty<custom_checkfn<APInt>>{{CheckFn}, &V};
500}
501
502/// Match a float or vector where CheckFn(ele) for each element is true.
503/// For vectors, poison elements are assumed to match.
505m_CheckedFp(function_ref<bool(const APFloat &)> CheckFn) {
506 return cstfp_pred_ty<custom_checkfn<APFloat>>{{CheckFn}};
507}
508
510m_CheckedFp(const Constant *&V, function_ref<bool(const APFloat &)> CheckFn) {
511 return cstfp_pred_ty<custom_checkfn<APFloat>>{{CheckFn}, &V};
512}
513
515 bool isValue(const APInt &C) const { return true; }
516};
517/// Match an integer or vector with any integral constant.
518/// For vectors, this includes constants with undefined elements.
522
524 bool isValue(const APInt &C) const { return C.isShiftedMask(); }
525};
526
530
532 bool isValue(const APInt &C) const { return C.isAllOnes(); }
533};
534/// Match an integer or vector with all bits set.
535/// For vectors, this includes constants with undefined elements.
539
543
545 bool isValue(const APInt &C) const { return C.isMaxSignedValue(); }
546};
547/// Match an integer or vector with values having all bits except for the high
548/// bit set (0x7f...).
549/// For vectors, this includes constants with undefined elements.
554 return V;
555}
556
558 bool isValue(const APInt &C) const { return C.isNegative(); }
559};
560/// Match an integer or vector of negative values.
561/// For vectors, this includes constants with undefined elements.
565inline api_pred_ty<is_negative> m_Negative(const APInt *&V) { return V; }
566
568 bool isValue(const APInt &C) const { return C.isNonNegative(); }
569};
570/// Match an integer or vector of non-negative values.
571/// For vectors, this includes constants with undefined elements.
575inline api_pred_ty<is_nonnegative> m_NonNegative(const APInt *&V) { return V; }
576
578 bool isValue(const APInt &C) const { return C.isStrictlyPositive(); }
579};
580/// Match an integer or vector of strictly positive values.
581/// For vectors, this includes constants with undefined elements.
586 return V;
587}
588
590 bool isValue(const APInt &C) const { return C.isNonPositive(); }
591};
592/// Match an integer or vector of non-positive values.
593/// For vectors, this includes constants with undefined elements.
597inline api_pred_ty<is_nonpositive> m_NonPositive(const APInt *&V) { return V; }
598
599struct is_one {
600 bool isValue(const APInt &C) const { return C.isOne(); }
601};
602/// Match an integer 1 or a vector with all elements equal to 1.
603/// For vectors, this includes constants with undefined elements.
605
607 bool isValue(const APInt &C) const { return C.isZero(); }
608};
609/// Match an integer 0 or a vector with all elements equal to 0.
610/// For vectors, this includes constants with undefined elements.
614
615struct is_zero {
616 template <typename ITy> bool match(ITy *V) const {
617 auto *C = dyn_cast<Constant>(V);
618 // FIXME: this should be able to do something for scalable vectors
619 return C && (C->isNullValue() || cst_pred_ty<is_zero_int>().match(C));
620 }
621};
622/// Match any null constant or a vector with all elements equal to 0.
623/// For vectors, this includes constants with undefined elements.
624inline is_zero m_Zero() { return is_zero(); }
625
626struct is_power2 {
627 bool isValue(const APInt &C) const { return C.isPowerOf2(); }
628};
629/// Match an integer or vector power-of-2.
630/// For vectors, this includes constants with undefined elements.
632inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
633
635 bool isValue(const APInt &C) const { return C.isNegatedPowerOf2(); }
636};
637/// Match a integer or vector negated power-of-2.
638/// For vectors, this includes constants with undefined elements.
643 return V;
644}
645
647 bool isValue(const APInt &C) const { return !C || C.isNegatedPowerOf2(); }
648};
649/// Match a integer or vector negated power-of-2.
650/// For vectors, this includes constants with undefined elements.
656 return V;
657}
658
660 bool isValue(const APInt &C) const { return !C || C.isPowerOf2(); }
661};
662/// Match an integer or vector of 0 or power-of-2 values.
663/// For vectors, this includes constants with undefined elements.
668 return V;
669}
670
672 bool isValue(const APInt &C) const { return C.isSignMask(); }
673};
674/// Match an integer or vector with only the sign bit(s) set.
675/// For vectors, this includes constants with undefined elements.
679
681 bool isValue(const APInt &C) const { return C.isMask(); }
682};
683/// Match an integer or vector with only the low bit(s) set.
684/// For vectors, this includes constants with undefined elements.
688inline api_pred_ty<is_lowbit_mask> m_LowBitMask(const APInt *&V) { return V; }
689
691 bool isValue(const APInt &C) const { return !C || C.isMask(); }
692};
693/// Match an integer or vector with only the low bit(s) set.
694/// For vectors, this includes constants with undefined elements.
699 return V;
700}
701
704 const APInt *Thr;
705 bool isValue(const APInt &C) const {
706 return ICmpInst::compare(C, *Thr, Pred);
707 }
708};
709/// Match an integer or vector with every element comparing 'pred' (eg/ne/...)
710/// to Threshold. For vectors, this includes constants with undefined elements.
714 P.Pred = Predicate;
715 P.Thr = &Threshold;
716 return P;
717}
718
719struct is_nan {
720 bool isValue(const APFloat &C) const { return C.isNaN(); }
721};
722/// Match an arbitrary NaN constant. This includes quiet and signalling nans.
723/// For vectors, this includes constants with undefined elements.
725
726struct is_nonnan {
727 bool isValue(const APFloat &C) const { return !C.isNaN(); }
728};
729/// Match a non-NaN FP constant.
730/// For vectors, this includes constants with undefined elements.
734
735struct is_inf {
736 bool isValue(const APFloat &C) const { return C.isInfinity(); }
737};
738/// Match a positive or negative infinity FP constant.
739/// For vectors, this includes constants with undefined elements.
741
742struct is_noninf {
743 bool isValue(const APFloat &C) const { return !C.isInfinity(); }
744};
745/// Match a non-infinity FP constant, i.e. finite or NaN.
746/// For vectors, this includes constants with undefined elements.
750
751struct is_finite {
752 bool isValue(const APFloat &C) const { return C.isFinite(); }
753};
754/// Match a finite FP constant, i.e. not infinity or NaN.
755/// For vectors, this includes constants with undefined elements.
759inline apf_pred_ty<is_finite> m_Finite(const APFloat *&V) { return V; }
760
762 bool isValue(const APFloat &C) const { return C.isFiniteNonZero(); }
763};
764/// Match a finite non-zero FP constant.
765/// For vectors, this includes constants with undefined elements.
770 return V;
771}
772
774 bool isValue(const APFloat &C) const { return C.isZero(); }
775};
776/// Match a floating-point negative zero or positive zero.
777/// For vectors, this includes constants with undefined elements.
781
783 bool isValue(const APFloat &C) const { return C.isPosZero(); }
784};
785/// Match a floating-point positive zero.
786/// For vectors, this includes constants with undefined elements.
790
792 bool isValue(const APFloat &C) const { return C.isNegZero(); }
793};
794/// Match a floating-point negative zero.
795/// For vectors, this includes constants with undefined elements.
799
801 bool isValue(const APFloat &C) const { return C.isNonZero(); }
802};
803/// Match a floating-point non-zero.
804/// For vectors, this includes constants with undefined elements.
808
810 bool isValue(const APFloat &C) const {
811 return !C.isDenormal() && C.isNonZero();
812 }
813};
814
815/// Match a floating-point non-zero that is not a denormal.
816/// For vectors, this includes constants with undefined elements.
820
821///////////////////////////////////////////////////////////////////////////////
822
823template <typename Class> struct bind_ty {
824 Class *&VR;
825
826 bind_ty(Class *&V) : VR(V) {}
827
828 template <typename ITy> bool match(ITy *V) const {
829 if (auto *CV = dyn_cast<Class>(V)) {
830 VR = CV;
831 return true;
832 }
833 return false;
834 }
835};
836
837/// Check whether the value has the given Class and matches the nested
838/// pattern. Capture it into the provided variable if successful.
839template <typename Class, typename MatchTy> struct bind_and_match_ty {
840 Class *&VR;
841 MatchTy Match;
842
843 bind_and_match_ty(Class *&V, const MatchTy &Match) : VR(V), Match(Match) {}
844
845 template <typename ITy> bool match(ITy *V) const {
846 auto *CV = dyn_cast<Class>(V);
847 if (CV && Match.match(V)) {
848 VR = CV;
849 return true;
850 }
851 return false;
852 }
853};
854
855/// Match a value, capturing it if we match.
856inline bind_ty<Value> m_Value(Value *&V) { return V; }
857inline bind_ty<const Value> m_Value(const Value *&V) { return V; }
858
859/// Match against the nested pattern, and capture the value if we match.
860template <typename MatchTy>
862 const MatchTy &Match) {
863 return {V, Match};
864}
865
866/// Match against the nested pattern, and capture the value if we match.
867template <typename MatchTy>
869 const MatchTy &Match) {
870 return {V, Match};
871}
872
873/// Match an instruction, capturing it if we match.
875
876/// Match against the nested pattern, and capture the instruction if we match.
877template <typename MatchTy>
879m_Instruction(Instruction *&I, const MatchTy &Match) {
880 return {I, Match};
881}
882
883/// Match a unary operator, capturing it if we match.
885/// Match a binary operator, capturing it if we match.
887/// Match a with overflow intrinsic, capturing it if we match.
893 return I;
894}
895
896/// Match an UndefValue, capturing the value if we match.
898
899/// Match a Constant, capturing the value if we match.
901
902/// Match a ConstantInt, capturing the value if we match.
904
905/// Match a ConstantFP, capturing the value if we match.
907
908/// Match a ConstantExpr, capturing the value if we match.
910
911/// Match a basic block value, capturing it if we match.
914 return V;
915}
916
917// TODO: Remove once UseConstant{Int,FP}ForScalableSplat is enabled by default,
918// and use m_Unless(m_ConstantExpr).
920 template <typename ITy> static bool isImmConstant(ITy *V) {
921 if (auto *CV = dyn_cast<Constant>(V)) {
922 if (!isa<ConstantExpr>(CV) && !CV->containsConstantExpression())
923 return true;
924
925 if (CV->getType()->isVectorTy()) {
926 if (auto *Splat = CV->getSplatValue(/*AllowPoison=*/true)) {
927 if (!isa<ConstantExpr>(Splat) &&
928 !Splat->containsConstantExpression()) {
929 return true;
930 }
931 }
932 }
933 }
934 return false;
935 }
936};
937
939 template <typename ITy> bool match(ITy *V) const { return isImmConstant(V); }
940};
941
942/// Match an arbitrary immediate Constant and ignore it.
944
947
949
950 template <typename ITy> bool match(ITy *V) const {
951 if (isImmConstant(V)) {
952 VR = cast<Constant>(V);
953 return true;
954 }
955 return false;
956 }
957};
958
959/// Match an immediate Constant, capturing the value if we match.
963
964/// Match a specified Value*.
966 const Value *Val;
967
968 specificval_ty(const Value *V) : Val(V) {}
969
970 template <typename ITy> bool match(ITy *V) const { return V == Val; }
971};
972
973/// Match if we have a specific specified value.
974inline specificval_ty m_Specific(const Value *V) { return V; }
975
976/// Stores a reference to the Value *, not the Value * itself,
977/// thus can be used in commutative matchers.
978template <typename Class> struct deferredval_ty {
979 Class *const &Val;
980
981 deferredval_ty(Class *const &V) : Val(V) {}
982
983 template <typename ITy> bool match(ITy *const V) const { return V == Val; }
984};
985
986/// Like m_Specific(), but works if the specific value to match is determined
987/// as part of the same match() expression. For example:
988/// m_Add(m_Value(X), m_Specific(X)) is incorrect, because m_Specific() will
989/// bind X before the pattern match starts.
990/// m_Add(m_Value(X), m_Deferred(X)) is correct, and will check against
991/// whichever value m_Value(X) populated.
992inline deferredval_ty<Value> m_Deferred(Value *const &V) { return V; }
994 return V;
995}
996
997/// Match a specified floating point value or vector of all elements of
998/// that value.
1000 double Val;
1001
1002 specific_fpval(double V) : Val(V) {}
1003
1004 template <typename ITy> bool match(ITy *V) const {
1005 if (const auto *CFP = dyn_cast<ConstantFP>(V))
1006 return CFP->isExactlyValue(Val);
1007 if (V->getType()->isVectorTy())
1008 if (const auto *C = dyn_cast<Constant>(V))
1009 if (auto *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue()))
1010 return CFP->isExactlyValue(Val);
1011 return false;
1012 }
1013};
1014
1015/// Match a specific floating point value or vector with all elements
1016/// equal to the value.
1017inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); }
1018
1019/// Match a float 1.0 or vector with all elements equal to 1.0.
1020inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
1021
1024
1026
1027 template <typename ITy> bool match(ITy *V) const {
1028 const APInt *ConstInt;
1029 if (!ap_match<APInt>(ConstInt, /*AllowPoison=*/false).match(V))
1030 return false;
1031 if (ConstInt->getActiveBits() > 64)
1032 return false;
1033 VR = ConstInt->getZExtValue();
1034 return true;
1035 }
1036};
1037
1038/// Match a specified integer value or vector of all elements of that
1039/// value.
1040template <bool AllowPoison> struct specific_intval {
1041 const APInt &Val;
1042
1043 specific_intval(const APInt &V) : Val(V) {}
1044
1045 template <typename ITy> bool match(ITy *V) const {
1046 const auto *CI = dyn_cast<ConstantInt>(V);
1047 if (!CI && V->getType()->isVectorTy())
1048 if (const auto *C = dyn_cast<Constant>(V))
1049 CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowPoison));
1050
1051 return CI && APInt::isSameValue(CI->getValue(), Val);
1052 }
1053};
1054
1055template <bool AllowPoison> struct specific_intval64 {
1057
1059
1060 template <typename ITy> bool match(ITy *V) const {
1061 const auto *CI = dyn_cast<ConstantInt>(V);
1062 if (!CI && V->getType()->isVectorTy())
1063 if (const auto *C = dyn_cast<Constant>(V))
1064 CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowPoison));
1065
1066 return CI && CI->getValue() == Val;
1067 }
1068};
1069
1070/// Match a specific integer value or vector with all elements equal to
1071/// the value.
1073 return specific_intval<false>(V);
1074}
1075
1079
1083
1087
1088/// Match a ConstantInt and bind to its value. This does not match
1089/// ConstantInts wider than 64-bits.
1091
1092/// Match a specified basic block value.
1095
1097
1098 template <typename ITy> bool match(ITy *V) const {
1099 const auto *BB = dyn_cast<BasicBlock>(V);
1100 return BB && BB == Val;
1101 }
1102};
1103
1104/// Match a specific basic block value.
1106 return specific_bbval(BB);
1107}
1108
1109/// A commutative-friendly version of m_Specific().
1111 return BB;
1112}
1114m_Deferred(const BasicBlock *const &BB) {
1115 return BB;
1116}
1117
1118//===----------------------------------------------------------------------===//
1119// Matcher for any binary operator.
1120//
1121template <typename LHS_t, typename RHS_t, bool Commutable = false>
1125
1126 // The evaluation order is always stable, regardless of Commutability.
1127 // The LHS is always matched first.
1128 AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
1129
1130 template <typename OpTy> bool match(OpTy *V) const {
1131 if (auto *I = dyn_cast<BinaryOperator>(V))
1132 return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
1133 (Commutable && L.match(I->getOperand(1)) &&
1134 R.match(I->getOperand(0)));
1135 return false;
1136 }
1137};
1138
1139template <typename LHS, typename RHS>
1140inline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) {
1141 return AnyBinaryOp_match<LHS, RHS>(L, R);
1142}
1143
1144//===----------------------------------------------------------------------===//
1145// Matcher for any unary operator.
1146// TODO fuse unary, binary matcher into n-ary matcher
1147//
1148template <typename OP_t> struct AnyUnaryOp_match {
1149 OP_t X;
1150
1151 AnyUnaryOp_match(const OP_t &X) : X(X) {}
1152
1153 template <typename OpTy> bool match(OpTy *V) const {
1154 if (auto *I = dyn_cast<UnaryOperator>(V))
1155 return X.match(I->getOperand(0));
1156 return false;
1157 }
1158};
1159
1160template <typename OP_t> inline AnyUnaryOp_match<OP_t> m_UnOp(const OP_t &X) {
1161 return AnyUnaryOp_match<OP_t>(X);
1162}
1163
1164//===----------------------------------------------------------------------===//
1165// Matchers for specific binary operators.
1166//
1167
1168template <typename LHS_t, typename RHS_t, unsigned Opcode,
1169 bool Commutable = false>
1173
1174 // The evaluation order is always stable, regardless of Commutability.
1175 // The LHS is always matched first.
1176 BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
1177
1178 template <typename OpTy> inline bool match(unsigned Opc, OpTy *V) const {
1179 if (V->getValueID() == Value::InstructionVal + Opc) {
1180 auto *I = cast<BinaryOperator>(V);
1181 return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
1182 (Commutable && L.match(I->getOperand(1)) &&
1183 R.match(I->getOperand(0)));
1184 }
1185 return false;
1186 }
1187
1188 template <typename OpTy> bool match(OpTy *V) const {
1189 return match(Opcode, V);
1190 }
1191};
1192
1193template <typename LHS, typename RHS>
1198
1199template <typename LHS, typename RHS>
1204
1205template <typename LHS, typename RHS>
1210
1211template <typename LHS, typename RHS>
1216
1217template <typename Op_t> struct FNeg_match {
1218 Op_t X;
1219
1220 FNeg_match(const Op_t &Op) : X(Op) {}
1221 template <typename OpTy> bool match(OpTy *V) const {
1222 auto *FPMO = dyn_cast<FPMathOperator>(V);
1223 if (!FPMO)
1224 return false;
1225
1226 if (FPMO->getOpcode() == Instruction::FNeg)
1227 return X.match(FPMO->getOperand(0));
1228
1229 if (FPMO->getOpcode() == Instruction::FSub) {
1230 if (FPMO->hasNoSignedZeros()) {
1231 // With 'nsz', any zero goes.
1232 if (!cstfp_pred_ty<is_any_zero_fp>().match(FPMO->getOperand(0)))
1233 return false;
1234 } else {
1235 // Without 'nsz', we need fsub -0.0, X exactly.
1236 if (!cstfp_pred_ty<is_neg_zero_fp>().match(FPMO->getOperand(0)))
1237 return false;
1238 }
1239
1240 return X.match(FPMO->getOperand(1));
1241 }
1242
1243 return false;
1244 }
1245};
1246
1247/// Match 'fneg X' as 'fsub -0.0, X'.
1248template <typename OpTy> inline FNeg_match<OpTy> m_FNeg(const OpTy &X) {
1249 return FNeg_match<OpTy>(X);
1250}
1251
1252/// Match 'fneg X' as 'fsub +-0.0, X'.
1253template <typename RHS>
1254inline BinaryOp_match<cstfp_pred_ty<is_any_zero_fp>, RHS, Instruction::FSub>
1255m_FNegNSZ(const RHS &X) {
1256 return m_FSub(m_AnyZeroFP(), X);
1257}
1258
1259template <typename LHS, typename RHS>
1264
1265template <typename LHS, typename RHS>
1270
1271template <typename LHS, typename RHS>
1276
1277template <typename LHS, typename RHS>
1282
1283template <typename LHS, typename RHS>
1288
1289template <typename LHS, typename RHS>
1294
1295template <typename LHS, typename RHS>
1300
1301template <typename LHS, typename RHS>
1306
1307template <typename LHS, typename RHS>
1312
1313template <typename LHS, typename RHS>
1318
1319template <typename LHS, typename RHS>
1324
1325template <typename LHS, typename RHS>
1330
1331template <typename LHS, typename RHS>
1336
1337template <typename LHS, typename RHS>
1342
1343template <typename LHS_t, unsigned Opcode> struct ShiftLike_match {
1346
1348
1349 template <typename OpTy> bool match(OpTy *V) const {
1350 if (auto *Op = dyn_cast<BinaryOperator>(V)) {
1351 if (Op->getOpcode() == Opcode)
1352 return m_ConstantInt(R).match(Op->getOperand(1)) &&
1353 L.match(Op->getOperand(0));
1354 }
1355 // Interpreted as shiftop V, 0
1356 R = 0;
1357 return L.match(V);
1358 }
1359};
1360
1361/// Matches shl L, ConstShAmt or L itself (R will be set to zero in this case).
1362template <typename LHS>
1367
1368/// Matches lshr L, ConstShAmt or L itself (R will be set to zero in this case).
1369template <typename LHS>
1374
1375/// Matches ashr L, ConstShAmt or L itself (R will be set to zero in this case).
1376template <typename LHS>
1381
1382template <typename LHS_t, typename RHS_t, unsigned Opcode,
1383 unsigned WrapFlags = 0, bool Commutable = false>
1387
1389 : L(LHS), R(RHS) {}
1390
1391 template <typename OpTy> bool match(OpTy *V) const {
1392 if (auto *Op = dyn_cast<OverflowingBinaryOperator>(V)) {
1393 if (Op->getOpcode() != Opcode)
1394 return false;
1396 !Op->hasNoUnsignedWrap())
1397 return false;
1398 if ((WrapFlags & OverflowingBinaryOperator::NoSignedWrap) &&
1399 !Op->hasNoSignedWrap())
1400 return false;
1401 return (L.match(Op->getOperand(0)) && R.match(Op->getOperand(1))) ||
1402 (Commutable && L.match(Op->getOperand(1)) &&
1403 R.match(Op->getOperand(0)));
1404 }
1405 return false;
1406 }
1407};
1408
1409template <typename LHS, typename RHS>
1410inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1412m_NSWAdd(const LHS &L, const RHS &R) {
1413 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1415 R);
1416}
1417template <typename LHS, typename RHS>
1418inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1420m_c_NSWAdd(const LHS &L, const RHS &R) {
1421 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1423 true>(L, R);
1424}
1425template <typename LHS, typename RHS>
1426inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
1428m_NSWSub(const LHS &L, const RHS &R) {
1429 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
1431 R);
1432}
1433template <typename LHS, typename RHS>
1434inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
1436m_NSWMul(const LHS &L, const RHS &R) {
1437 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
1439 R);
1440}
1441template <typename LHS, typename RHS>
1442inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
1444m_NSWShl(const LHS &L, const RHS &R) {
1445 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
1447 R);
1448}
1449
1450template <typename LHS, typename RHS>
1451inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1453m_NUWAdd(const LHS &L, const RHS &R) {
1454 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1456 L, R);
1457}
1458
1459template <typename LHS, typename RHS>
1461 LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true>
1462m_c_NUWAdd(const LHS &L, const RHS &R) {
1463 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1465 true>(L, R);
1466}
1467
1468template <typename LHS, typename RHS>
1469inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
1471m_NUWSub(const LHS &L, const RHS &R) {
1472 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
1474 L, R);
1475}
1476template <typename LHS, typename RHS>
1477inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
1479m_NUWMul(const LHS &L, const RHS &R) {
1480 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
1482 L, R);
1483}
1484template <typename LHS, typename RHS>
1485inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
1487m_NUWShl(const LHS &L, const RHS &R) {
1488 return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
1490 L, R);
1491}
1492
1493template <typename LHS_t, typename RHS_t, bool Commutable = false>
1495 : public BinaryOp_match<LHS_t, RHS_t, 0, Commutable> {
1496 unsigned Opcode;
1497
1499 : BinaryOp_match<LHS_t, RHS_t, 0, Commutable>(LHS, RHS), Opcode(Opcode) {}
1500
1501 template <typename OpTy> bool match(OpTy *V) const {
1503 }
1504};
1505
1506/// Matches a specific opcode.
1507template <typename LHS, typename RHS>
1508inline SpecificBinaryOp_match<LHS, RHS> m_BinOp(unsigned Opcode, const LHS &L,
1509 const RHS &R) {
1510 return SpecificBinaryOp_match<LHS, RHS>(Opcode, L, R);
1511}
1512
1513template <typename LHS, typename RHS, bool Commutable = false>
1517
1518 DisjointOr_match(const LHS &L, const RHS &R) : L(L), R(R) {}
1519
1520 template <typename OpTy> bool match(OpTy *V) const {
1521 if (auto *PDI = dyn_cast<PossiblyDisjointInst>(V)) {
1522 assert(PDI->getOpcode() == Instruction::Or && "Only or can be disjoint");
1523 if (!PDI->isDisjoint())
1524 return false;
1525 return (L.match(PDI->getOperand(0)) && R.match(PDI->getOperand(1))) ||
1526 (Commutable && L.match(PDI->getOperand(1)) &&
1527 R.match(PDI->getOperand(0)));
1528 }
1529 return false;
1530 }
1531};
1532
1533template <typename LHS, typename RHS>
1535 return DisjointOr_match<LHS, RHS>(L, R);
1536}
1537
1538template <typename LHS, typename RHS>
1540 const RHS &R) {
1542}
1543
1544/// Match either "add" or "or disjoint".
1545template <typename LHS, typename RHS>
1548m_AddLike(const LHS &L, const RHS &R) {
1549 return m_CombineOr(m_Add(L, R), m_DisjointOr(L, R));
1550}
1551
1552/// Match either "add nsw" or "or disjoint"
1553template <typename LHS, typename RHS>
1554inline match_combine_or<
1555 OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1558m_NSWAddLike(const LHS &L, const RHS &R) {
1559 return m_CombineOr(m_NSWAdd(L, R), m_DisjointOr(L, R));
1560}
1561
1562/// Match either "add nuw" or "or disjoint"
1563template <typename LHS, typename RHS>
1564inline match_combine_or<
1565 OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
1568m_NUWAddLike(const LHS &L, const RHS &R) {
1569 return m_CombineOr(m_NUWAdd(L, R), m_DisjointOr(L, R));
1570}
1571
1572template <typename LHS, typename RHS>
1576
1577 XorLike_match(const LHS &L, const RHS &R) : L(L), R(R) {}
1578
1579 template <typename OpTy> bool match(OpTy *V) const {
1580 if (auto *Op = dyn_cast<BinaryOperator>(V)) {
1581 if (Op->getOpcode() == Instruction::Sub && Op->hasNoUnsignedWrap() &&
1582 PatternMatch::match(Op->getOperand(0), m_LowBitMask()))
1583 ; // Pass
1584 else if (Op->getOpcode() != Instruction::Xor)
1585 return false;
1586 return (L.match(Op->getOperand(0)) && R.match(Op->getOperand(1))) ||
1587 (L.match(Op->getOperand(1)) && R.match(Op->getOperand(0)));
1588 }
1589 return false;
1590 }
1591};
1592
1593/// Match either `(xor L, R)`, `(xor R, L)` or `(sub nuw R, L)` iff `R.isMask()`
1594/// Only commutative matcher as the `sub` will need to swap the L and R.
1595template <typename LHS, typename RHS>
1596inline auto m_c_XorLike(const LHS &L, const RHS &R) {
1597 return XorLike_match<LHS, RHS>(L, R);
1598}
1599
1600//===----------------------------------------------------------------------===//
1601// Class that matches a group of binary opcodes.
1602//
1603template <typename LHS_t, typename RHS_t, typename Predicate,
1604 bool Commutable = false>
1605struct BinOpPred_match : Predicate {
1608
1609 BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
1610
1611 template <typename OpTy> bool match(OpTy *V) const {
1612 if (auto *I = dyn_cast<Instruction>(V))
1613 return this->isOpType(I->getOpcode()) &&
1614 ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
1615 (Commutable && L.match(I->getOperand(1)) &&
1616 R.match(I->getOperand(0))));
1617 return false;
1618 }
1619};
1620
1622 bool isOpType(unsigned Opcode) const { return Instruction::isShift(Opcode); }
1623};
1624
1626 bool isOpType(unsigned Opcode) const {
1627 return Opcode == Instruction::LShr || Opcode == Instruction::AShr;
1628 }
1629};
1630
1632 bool isOpType(unsigned Opcode) const {
1633 return Opcode == Instruction::LShr || Opcode == Instruction::Shl;
1634 }
1635};
1636
1638 bool isOpType(unsigned Opcode) const {
1639 return Instruction::isBitwiseLogicOp(Opcode);
1640 }
1641};
1642
1644 bool isOpType(unsigned Opcode) const {
1645 return Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
1646 }
1647};
1648
1650 bool isOpType(unsigned Opcode) const {
1651 return Opcode == Instruction::SRem || Opcode == Instruction::URem;
1652 }
1653};
1654
1655/// Matches shift operations.
1656template <typename LHS, typename RHS>
1658 const RHS &R) {
1660}
1661
1662/// Matches logical shift operations.
1663template <typename LHS, typename RHS>
1668
1669/// Matches logical shift operations.
1670template <typename LHS, typename RHS>
1672m_LogicalShift(const LHS &L, const RHS &R) {
1674}
1675
1676/// Matches bitwise logic operations.
1677template <typename LHS, typename RHS>
1679m_BitwiseLogic(const LHS &L, const RHS &R) {
1681}
1682
1683/// Matches bitwise logic operations in either order.
1684template <typename LHS, typename RHS>
1689
1690/// Matches integer division operations.
1691template <typename LHS, typename RHS>
1693 const RHS &R) {
1695}
1696
1697/// Matches integer remainder operations.
1698template <typename LHS, typename RHS>
1700 const RHS &R) {
1702}
1703
1704//===----------------------------------------------------------------------===//
1705// Class that matches exact binary ops.
1706//
1707template <typename SubPattern_t> struct Exact_match {
1708 SubPattern_t SubPattern;
1709
1710 Exact_match(const SubPattern_t &SP) : SubPattern(SP) {}
1711
1712 template <typename OpTy> bool match(OpTy *V) const {
1713 if (auto *PEO = dyn_cast<PossiblyExactOperator>(V))
1714 return PEO->isExact() && SubPattern.match(V);
1715 return false;
1716 }
1717};
1718
1719template <typename T> inline Exact_match<T> m_Exact(const T &SubPattern) {
1720 return SubPattern;
1721}
1722
1723//===----------------------------------------------------------------------===//
1724// Matchers for CmpInst classes
1725//
1726
1727template <typename LHS_t, typename RHS_t, typename Class,
1728 bool Commutable = false>
1733
1734 // The evaluation order is always stable, regardless of Commutability.
1735 // The LHS is always matched first.
1737 : Predicate(&Pred), L(LHS), R(RHS) {}
1739 : Predicate(nullptr), L(LHS), R(RHS) {}
1740
1741 template <typename OpTy> bool match(OpTy *V) const {
1742 if (auto *I = dyn_cast<Class>(V)) {
1743 if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
1744 if (Predicate)
1746 return true;
1747 }
1748 if (Commutable && L.match(I->getOperand(1)) &&
1749 R.match(I->getOperand(0))) {
1750 if (Predicate)
1752 return true;
1753 }
1754 }
1755 return false;
1756 }
1757};
1758
1759template <typename LHS, typename RHS>
1761 const RHS &R) {
1762 return CmpClass_match<LHS, RHS, CmpInst>(Pred, L, R);
1763}
1764
1765template <typename LHS, typename RHS>
1767 const LHS &L, const RHS &R) {
1768 return CmpClass_match<LHS, RHS, ICmpInst>(Pred, L, R);
1769}
1770
1771template <typename LHS, typename RHS>
1773 const LHS &L, const RHS &R) {
1774 return CmpClass_match<LHS, RHS, FCmpInst>(Pred, L, R);
1775}
1776
1777template <typename LHS, typename RHS>
1780}
1781
1782template <typename LHS, typename RHS>
1785}
1786
1787template <typename LHS, typename RHS>
1790}
1791
1792// Same as CmpClass, but instead of saving Pred as out output variable, match a
1793// specific input pred for equality.
1794template <typename LHS_t, typename RHS_t, typename Class,
1795 bool Commutable = false>
1800
1802 : Predicate(Pred), L(LHS), R(RHS) {}
1803
1804 template <typename OpTy> bool match(OpTy *V) const {
1805 if (auto *I = dyn_cast<Class>(V)) {
1807 L.match(I->getOperand(0)) && R.match(I->getOperand(1)))
1808 return true;
1809 if constexpr (Commutable) {
1812 L.match(I->getOperand(1)) && R.match(I->getOperand(0)))
1813 return true;
1814 }
1815 }
1816
1817 return false;
1818 }
1819};
1820
1821template <typename LHS, typename RHS>
1823m_SpecificCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R) {
1824 return SpecificCmpClass_match<LHS, RHS, CmpInst>(MatchPred, L, R);
1825}
1826
1827template <typename LHS, typename RHS>
1829m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R) {
1830 return SpecificCmpClass_match<LHS, RHS, ICmpInst>(MatchPred, L, R);
1831}
1832
1833template <typename LHS, typename RHS>
1835m_c_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R) {
1837}
1838
1839template <typename LHS, typename RHS>
1841m_SpecificFCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R) {
1842 return SpecificCmpClass_match<LHS, RHS, FCmpInst>(MatchPred, L, R);
1843}
1844
1845//===----------------------------------------------------------------------===//
1846// Matchers for instructions with a given opcode and number of operands.
1847//
1848
1849/// Matches instructions with Opcode and three operands.
1850template <typename T0, unsigned Opcode> struct OneOps_match {
1852
1853 OneOps_match(const T0 &Op1) : Op1(Op1) {}
1854
1855 template <typename OpTy> bool match(OpTy *V) const {
1856 if (V->getValueID() == Value::InstructionVal + Opcode) {
1857 auto *I = cast<Instruction>(V);
1858 return Op1.match(I->getOperand(0));
1859 }
1860 return false;
1861 }
1862};
1863
1864/// Matches instructions with Opcode and three operands.
1865template <typename T0, typename T1, unsigned Opcode> struct TwoOps_match {
1868
1869 TwoOps_match(const T0 &Op1, const T1 &Op2) : Op1(Op1), Op2(Op2) {}
1870
1871 template <typename OpTy> bool match(OpTy *V) const {
1872 if (V->getValueID() == Value::InstructionVal + Opcode) {
1873 auto *I = cast<Instruction>(V);
1874 return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1));
1875 }
1876 return false;
1877 }
1878};
1879
1880/// Matches instructions with Opcode and three operands.
1881template <typename T0, typename T1, typename T2, unsigned Opcode,
1882 bool CommutableOp2Op3 = false>
1887
1888 ThreeOps_match(const T0 &Op1, const T1 &Op2, const T2 &Op3)
1889 : Op1(Op1), Op2(Op2), Op3(Op3) {}
1890
1891 template <typename OpTy> bool match(OpTy *V) const {
1892 if (V->getValueID() == Value::InstructionVal + Opcode) {
1893 auto *I = cast<Instruction>(V);
1894 if (!Op1.match(I->getOperand(0)))
1895 return false;
1896 if (Op2.match(I->getOperand(1)) && Op3.match(I->getOperand(2)))
1897 return true;
1898 return CommutableOp2Op3 && Op2.match(I->getOperand(2)) &&
1899 Op3.match(I->getOperand(1));
1900 }
1901 return false;
1902 }
1903};
1904
1905/// Matches instructions with Opcode and any number of operands
1906template <unsigned Opcode, typename... OperandTypes> struct AnyOps_match {
1907 std::tuple<OperandTypes...> Operands;
1908
1909 AnyOps_match(const OperandTypes &...Ops) : Operands(Ops...) {}
1910
1911 // Operand matching works by recursively calling match_operands, matching the
1912 // operands left to right. The first version is called for each operand but
1913 // the last, for which the second version is called. The second version of
1914 // match_operands is also used to match each individual operand.
1915 template <int Idx, int Last>
1916 std::enable_if_t<Idx != Last, bool>
1920
1921 template <int Idx, int Last>
1922 std::enable_if_t<Idx == Last, bool>
1924 return std::get<Idx>(Operands).match(I->getOperand(Idx));
1925 }
1926
1927 template <typename OpTy> bool match(OpTy *V) const {
1928 if (V->getValueID() == Value::InstructionVal + Opcode) {
1929 auto *I = cast<Instruction>(V);
1930 return I->getNumOperands() == sizeof...(OperandTypes) &&
1931 match_operands<0, sizeof...(OperandTypes) - 1>(I);
1932 }
1933 return false;
1934 }
1935};
1936
1937/// Matches SelectInst.
1938template <typename Cond, typename LHS, typename RHS>
1940m_Select(const Cond &C, const LHS &L, const RHS &R) {
1942}
1943
1944/// This matches a select of two constants, e.g.:
1945/// m_SelectCst<-1, 0>(m_Value(V))
1946template <int64_t L, int64_t R, typename Cond>
1948 Instruction::Select>
1951}
1952
1953/// Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
1954template <typename LHS, typename RHS>
1955inline ThreeOps_match<decltype(m_Value()), LHS, RHS, Instruction::Select, true>
1956m_c_Select(const LHS &L, const RHS &R) {
1957 return ThreeOps_match<decltype(m_Value()), LHS, RHS, Instruction::Select,
1958 true>(m_Value(), L, R);
1959}
1960
1961/// Matches FreezeInst.
1962template <typename OpTy>
1966
1967/// Matches InsertElementInst.
1968template <typename Val_t, typename Elt_t, typename Idx_t>
1970m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx) {
1972 Val, Elt, Idx);
1973}
1974
1975/// Matches ExtractElementInst.
1976template <typename Val_t, typename Idx_t>
1978m_ExtractElt(const Val_t &Val, const Idx_t &Idx) {
1980}
1981
1982/// Matches shuffle.
1983template <typename T0, typename T1, typename T2> struct Shuffle_match {
1987
1988 Shuffle_match(const T0 &Op1, const T1 &Op2, const T2 &Mask)
1989 : Op1(Op1), Op2(Op2), Mask(Mask) {}
1990
1991 template <typename OpTy> bool match(OpTy *V) const {
1992 if (auto *I = dyn_cast<ShuffleVectorInst>(V)) {
1993 return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1)) &&
1994 Mask.match(I->getShuffleMask());
1995 }
1996 return false;
1997 }
1998};
1999
2000struct m_Mask {
2003 bool match(ArrayRef<int> Mask) const {
2004 MaskRef = Mask;
2005 return true;
2006 }
2007};
2008
2010 bool match(ArrayRef<int> Mask) const {
2011 return all_of(Mask, [](int Elem) { return Elem == 0 || Elem == -1; });
2012 }
2013};
2014
2018 bool match(ArrayRef<int> Mask) const { return Val == Mask; }
2019};
2020
2024 bool match(ArrayRef<int> Mask) const {
2025 const auto *First = find_if(Mask, [](int Elem) { return Elem != -1; });
2026 if (First == Mask.end())
2027 return false;
2028 SplatIndex = *First;
2029 return all_of(Mask,
2030 [First](int Elem) { return Elem == *First || Elem == -1; });
2031 }
2032};
2033
2034template <typename PointerOpTy, typename OffsetOpTy> struct PtrAdd_match {
2035 PointerOpTy PointerOp;
2036 OffsetOpTy OffsetOp;
2037
2038 PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
2040
2041 template <typename OpTy> bool match(OpTy *V) const {
2042 auto *GEP = dyn_cast<GEPOperator>(V);
2043 return GEP && GEP->getSourceElementType()->isIntegerTy(8) &&
2044 PointerOp.match(GEP->getPointerOperand()) &&
2045 OffsetOp.match(GEP->idx_begin()->get());
2046 }
2047};
2048
2049/// Matches ShuffleVectorInst independently of mask value.
2050template <typename V1_t, typename V2_t>
2052m_Shuffle(const V1_t &v1, const V2_t &v2) {
2054}
2055
2056template <typename V1_t, typename V2_t, typename Mask_t>
2058m_Shuffle(const V1_t &v1, const V2_t &v2, const Mask_t &mask) {
2060}
2061
2062/// Matches LoadInst.
2063template <typename OpTy>
2067
2068/// Matches StoreInst.
2069template <typename ValueOpTy, typename PointerOpTy>
2071m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) {
2073 PointerOp);
2074}
2075
2076/// Matches GetElementPtrInst.
2077template <typename... OperandTypes>
2078inline auto m_GEP(const OperandTypes &...Ops) {
2079 return AnyOps_match<Instruction::GetElementPtr, OperandTypes...>(Ops...);
2080}
2081
2082/// Matches GEP with i8 source element type
2083template <typename PointerOpTy, typename OffsetOpTy>
2085m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) {
2087}
2088
2089//===----------------------------------------------------------------------===//
2090// Matchers for CastInst classes
2091//
2092
2093template <typename Op_t, unsigned Opcode> struct CastOperator_match {
2094 Op_t Op;
2095
2096 CastOperator_match(const Op_t &OpMatch) : Op(OpMatch) {}
2097
2098 template <typename OpTy> bool match(OpTy *V) const {
2099 if (auto *O = dyn_cast<Operator>(V))
2100 return O->getOpcode() == Opcode && Op.match(O->getOperand(0));
2101 return false;
2102 }
2103};
2104
2105template <typename Op_t, typename Class> struct CastInst_match {
2106 Op_t Op;
2107
2108 CastInst_match(const Op_t &OpMatch) : Op(OpMatch) {}
2109
2110 template <typename OpTy> bool match(OpTy *V) const {
2111 if (auto *I = dyn_cast<Class>(V))
2112 return Op.match(I->getOperand(0));
2113 return false;
2114 }
2115};
2116
2117template <typename Op_t> struct PtrToIntSameSize_match {
2119 Op_t Op;
2120
2121 PtrToIntSameSize_match(const DataLayout &DL, const Op_t &OpMatch)
2122 : DL(DL), Op(OpMatch) {}
2123
2124 template <typename OpTy> bool match(OpTy *V) const {
2125 if (auto *O = dyn_cast<Operator>(V))
2126 return O->getOpcode() == Instruction::PtrToInt &&
2127 DL.getTypeSizeInBits(O->getType()) ==
2128 DL.getTypeSizeInBits(O->getOperand(0)->getType()) &&
2129 Op.match(O->getOperand(0));
2130 return false;
2131 }
2132};
2133
2134template <typename Op_t> struct NNegZExt_match {
2135 Op_t Op;
2136
2137 NNegZExt_match(const Op_t &OpMatch) : Op(OpMatch) {}
2138
2139 template <typename OpTy> bool match(OpTy *V) const {
2140 if (auto *I = dyn_cast<ZExtInst>(V))
2141 return I->hasNonNeg() && Op.match(I->getOperand(0));
2142 return false;
2143 }
2144};
2145
2146template <typename Op_t, unsigned WrapFlags = 0> struct NoWrapTrunc_match {
2147 Op_t Op;
2148
2149 NoWrapTrunc_match(const Op_t &OpMatch) : Op(OpMatch) {}
2150
2151 template <typename OpTy> bool match(OpTy *V) const {
2152 if (auto *I = dyn_cast<TruncInst>(V))
2153 return (I->getNoWrapKind() & WrapFlags) == WrapFlags &&
2154 Op.match(I->getOperand(0));
2155 return false;
2156 }
2157};
2158
2159/// Matches BitCast.
2160template <typename OpTy>
2165
2166template <typename Op_t> struct ElementWiseBitCast_match {
2167 Op_t Op;
2168
2169 ElementWiseBitCast_match(const Op_t &OpMatch) : Op(OpMatch) {}
2170
2171 template <typename OpTy> bool match(OpTy *V) const {
2172 auto *I = dyn_cast<BitCastInst>(V);
2173 if (!I)
2174 return false;
2175 Type *SrcType = I->getSrcTy();
2176 Type *DstType = I->getType();
2177 // Make sure the bitcast doesn't change between scalar and vector and
2178 // doesn't change the number of vector elements.
2179 if (SrcType->isVectorTy() != DstType->isVectorTy())
2180 return false;
2181 if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcType);
2182 SrcVecTy && SrcVecTy->getElementCount() !=
2183 cast<VectorType>(DstType)->getElementCount())
2184 return false;
2185 return Op.match(I->getOperand(0));
2186 }
2187};
2188
2189template <typename OpTy>
2193
2194/// Matches PtrToInt.
2195template <typename OpTy>
2200
2201template <typename OpTy>
2206
2207/// Matches PtrToAddr.
2208template <typename OpTy>
2213
2214/// Matches PtrToInt or PtrToAddr.
2215template <typename OpTy> inline auto m_PtrToIntOrAddr(const OpTy &Op) {
2217}
2218
2219/// Matches IntToPtr.
2220template <typename OpTy>
2225
2226/// Matches any cast or self. Used to ignore casts.
2227template <typename OpTy>
2229m_CastOrSelf(const OpTy &Op) {
2231}
2232
2233/// Matches Trunc.
2234template <typename OpTy>
2238
2239/// Matches trunc nuw.
2240template <typename OpTy>
2245
2246/// Matches trunc nsw.
2247template <typename OpTy>
2252
2253template <typename OpTy>
2255m_TruncOrSelf(const OpTy &Op) {
2256 return m_CombineOr(m_Trunc(Op), Op);
2257}
2258
2259/// Matches SExt.
2260template <typename OpTy>
2264
2265/// Matches ZExt.
2266template <typename OpTy>
2270
2271template <typename OpTy>
2273 return NNegZExt_match<OpTy>(Op);
2274}
2275
2276template <typename OpTy>
2278m_ZExtOrSelf(const OpTy &Op) {
2279 return m_CombineOr(m_ZExt(Op), Op);
2280}
2281
2282template <typename OpTy>
2284m_SExtOrSelf(const OpTy &Op) {
2285 return m_CombineOr(m_SExt(Op), Op);
2286}
2287
2288/// Match either "sext" or "zext nneg".
2289template <typename OpTy>
2291m_SExtLike(const OpTy &Op) {
2292 return m_CombineOr(m_SExt(Op), m_NNegZExt(Op));
2293}
2294
2295template <typename OpTy>
2298m_ZExtOrSExt(const OpTy &Op) {
2299 return m_CombineOr(m_ZExt(Op), m_SExt(Op));
2300}
2301
2302template <typename OpTy>
2305 OpTy>
2307 return m_CombineOr(m_ZExtOrSExt(Op), Op);
2308}
2309
2310template <typename OpTy>
2313 OpTy>
2316}
2317
2318template <typename OpTy>
2322
2323template <typename OpTy>
2327
2328template <typename OpTy>
2332
2333template <typename OpTy>
2337
2338template <typename OpTy>
2342
2343template <typename OpTy>
2347
2348//===----------------------------------------------------------------------===//
2349// Matchers for control flow.
2350//
2351
2352struct br_match {
2354
2356
2357 template <typename OpTy> bool match(OpTy *V) const {
2358 if (auto *BI = dyn_cast<BranchInst>(V))
2359 if (BI->isUnconditional()) {
2360 Succ = BI->getSuccessor(0);
2361 return true;
2362 }
2363 return false;
2364 }
2365};
2366
2367inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
2368
2369template <typename Cond_t, typename TrueBlock_t, typename FalseBlock_t>
2371 Cond_t Cond;
2372 TrueBlock_t T;
2373 FalseBlock_t F;
2374
2375 brc_match(const Cond_t &C, const TrueBlock_t &t, const FalseBlock_t &f)
2376 : Cond(C), T(t), F(f) {}
2377
2378 template <typename OpTy> bool match(OpTy *V) const {
2379 if (auto *BI = dyn_cast<BranchInst>(V))
2380 if (BI->isConditional() && Cond.match(BI->getCondition()))
2381 return T.match(BI->getSuccessor(0)) && F.match(BI->getSuccessor(1));
2382 return false;
2383 }
2384};
2385
2386template <typename Cond_t>
2392
2393template <typename Cond_t, typename TrueBlock_t, typename FalseBlock_t>
2395m_Br(const Cond_t &C, const TrueBlock_t &T, const FalseBlock_t &F) {
2397}
2398
2399//===----------------------------------------------------------------------===//
2400// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y).
2401//
2402
2403template <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t,
2404 bool Commutable = false>
2406 using PredType = Pred_t;
2409
2410 // The evaluation order is always stable, regardless of Commutability.
2411 // The LHS is always matched first.
2412 MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
2413
2414 template <typename OpTy> bool match(OpTy *V) const {
2415 if (auto *II = dyn_cast<IntrinsicInst>(V)) {
2416 Intrinsic::ID IID = II->getIntrinsicID();
2417 if ((IID == Intrinsic::smax && Pred_t::match(ICmpInst::ICMP_SGT)) ||
2418 (IID == Intrinsic::smin && Pred_t::match(ICmpInst::ICMP_SLT)) ||
2419 (IID == Intrinsic::umax && Pred_t::match(ICmpInst::ICMP_UGT)) ||
2420 (IID == Intrinsic::umin && Pred_t::match(ICmpInst::ICMP_ULT))) {
2421 Value *LHS = II->getOperand(0), *RHS = II->getOperand(1);
2422 return (L.match(LHS) && R.match(RHS)) ||
2423 (Commutable && L.match(RHS) && R.match(LHS));
2424 }
2425 }
2426 // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x".
2427 auto *SI = dyn_cast<SelectInst>(V);
2428 if (!SI)
2429 return false;
2430 auto *Cmp = dyn_cast<CmpInst_t>(SI->getCondition());
2431 if (!Cmp)
2432 return false;
2433 // At this point we have a select conditioned on a comparison. Check that
2434 // it is the values returned by the select that are being compared.
2435 auto *TrueVal = SI->getTrueValue();
2436 auto *FalseVal = SI->getFalseValue();
2437 auto *LHS = Cmp->getOperand(0);
2438 auto *RHS = Cmp->getOperand(1);
2439 if ((TrueVal != LHS || FalseVal != RHS) &&
2440 (TrueVal != RHS || FalseVal != LHS))
2441 return false;
2442 typename CmpInst_t::Predicate Pred =
2443 LHS == TrueVal ? Cmp->getPredicate() : Cmp->getInversePredicate();
2444 // Does "(x pred y) ? x : y" represent the desired max/min operation?
2445 if (!Pred_t::match(Pred))
2446 return false;
2447 // It does! Bind the operands.
2448 return (L.match(LHS) && R.match(RHS)) ||
2449 (Commutable && L.match(RHS) && R.match(LHS));
2450 }
2451};
2452
2453/// Helper class for identifying signed max predicates.
2455 static bool match(ICmpInst::Predicate Pred) {
2456 return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE;
2457 }
2458};
2459
2460/// Helper class for identifying signed min predicates.
2462 static bool match(ICmpInst::Predicate Pred) {
2463 return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE;
2464 }
2465};
2466
2467/// Helper class for identifying unsigned max predicates.
2469 static bool match(ICmpInst::Predicate Pred) {
2470 return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE;
2471 }
2472};
2473
2474/// Helper class for identifying unsigned min predicates.
2476 static bool match(ICmpInst::Predicate Pred) {
2477 return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE;
2478 }
2479};
2480
2481/// Helper class for identifying ordered max predicates.
2483 static bool match(FCmpInst::Predicate Pred) {
2484 return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE;
2485 }
2486};
2487
2488/// Helper class for identifying ordered min predicates.
2490 static bool match(FCmpInst::Predicate Pred) {
2491 return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE;
2492 }
2493};
2494
2495/// Helper class for identifying unordered max predicates.
2497 static bool match(FCmpInst::Predicate Pred) {
2498 return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE;
2499 }
2500};
2501
2502/// Helper class for identifying unordered min predicates.
2504 static bool match(FCmpInst::Predicate Pred) {
2505 return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE;
2506 }
2507};
2508
2509template <typename LHS, typename RHS>
2514
2515template <typename LHS, typename RHS>
2520
2521template <typename LHS, typename RHS>
2526
2527template <typename LHS, typename RHS>
2532
2533template <typename LHS, typename RHS>
2534inline match_combine_or<
2539m_MaxOrMin(const LHS &L, const RHS &R) {
2540 return m_CombineOr(m_CombineOr(m_SMax(L, R), m_SMin(L, R)),
2541 m_CombineOr(m_UMax(L, R), m_UMin(L, R)));
2542}
2543
2544/// Match an 'ordered' floating point maximum function.
2545/// Floating point has one special value 'NaN'. Therefore, there is no total
2546/// order. However, if we can ignore the 'NaN' value (for example, because of a
2547/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
2548/// semantics. In the presence of 'NaN' we have to preserve the original
2549/// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate.
2550///
2551/// max(L, R) iff L and R are not NaN
2552/// m_OrdFMax(L, R) = R iff L or R are NaN
2553template <typename LHS, typename RHS>
2558
2559/// Match an 'ordered' floating point minimum function.
2560/// Floating point has one special value 'NaN'. Therefore, there is no total
2561/// order. However, if we can ignore the 'NaN' value (for example, because of a
2562/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
2563/// semantics. In the presence of 'NaN' we have to preserve the original
2564/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
2565///
2566/// min(L, R) iff L and R are not NaN
2567/// m_OrdFMin(L, R) = R iff L or R are NaN
2568template <typename LHS, typename RHS>
2573
2574/// Match an 'unordered' floating point maximum function.
2575/// Floating point has one special value 'NaN'. Therefore, there is no total
2576/// order. However, if we can ignore the 'NaN' value (for example, because of a
2577/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
2578/// semantics. In the presence of 'NaN' we have to preserve the original
2579/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
2580///
2581/// max(L, R) iff L and R are not NaN
2582/// m_UnordFMax(L, R) = L iff L or R are NaN
2583template <typename LHS, typename RHS>
2585m_UnordFMax(const LHS &L, const RHS &R) {
2587}
2588
2589/// Match an 'unordered' floating point minimum function.
2590/// Floating point has one special value 'NaN'. Therefore, there is no total
2591/// order. However, if we can ignore the 'NaN' value (for example, because of a
2592/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
2593/// semantics. In the presence of 'NaN' we have to preserve the original
2594/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
2595///
2596/// min(L, R) iff L and R are not NaN
2597/// m_UnordFMin(L, R) = L iff L or R are NaN
2598template <typename LHS, typename RHS>
2600m_UnordFMin(const LHS &L, const RHS &R) {
2602}
2603
2604/// Match an 'ordered' or 'unordered' floating point maximum function.
2605/// Floating point has one special value 'NaN'. Therefore, there is no total
2606/// order. However, if we can ignore the 'NaN' value (for example, because of a
2607/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
2608/// semantics.
2609template <typename LHS, typename RHS>
2616
2617/// Match an 'ordered' or 'unordered' floating point minimum function.
2618/// Floating point has one special value 'NaN'. Therefore, there is no total
2619/// order. However, if we can ignore the 'NaN' value (for example, because of a
2620/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
2621/// semantics.
2622template <typename LHS, typename RHS>
2629
2630/// Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
2631/// NOTE: we first match the 'Not' (by matching '-1'),
2632/// and only then match the inner matcher!
2633template <typename ValTy>
2634inline BinaryOp_match<cst_pred_ty<is_all_ones>, ValTy, Instruction::Xor, true>
2635m_Not(const ValTy &V) {
2636 return m_c_Xor(m_AllOnes(), V);
2637}
2638
2639template <typename ValTy>
2640inline BinaryOp_match<cst_pred_ty<is_all_ones, false>, ValTy, Instruction::Xor,
2641 true>
2642m_NotForbidPoison(const ValTy &V) {
2643 return m_c_Xor(m_AllOnesForbidPoison(), V);
2644}
2645
2646//===----------------------------------------------------------------------===//
2647// Matchers for overflow check patterns: e.g. (a + b) u< a, (a ^ -1) <u b
2648// Note that S might be matched to other instructions than AddInst.
2649//
2650
2651template <typename LHS_t, typename RHS_t, typename Sum_t>
2655 Sum_t S;
2656
2657 UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S)
2658 : L(L), R(R), S(S) {}
2659
2660 template <typename OpTy> bool match(OpTy *V) const {
2661 Value *ICmpLHS, *ICmpRHS;
2662 CmpPredicate Pred;
2663 if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V))
2664 return false;
2665
2666 Value *AddLHS, *AddRHS;
2667 auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS));
2668
2669 // (a + b) u< a, (a + b) u< b
2670 if (Pred == ICmpInst::ICMP_ULT)
2671 if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS))
2672 return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS);
2673
2674 // a >u (a + b), b >u (a + b)
2675 if (Pred == ICmpInst::ICMP_UGT)
2676 if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS))
2677 return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
2678
2679 Value *Op1;
2680 auto XorExpr = m_OneUse(m_Not(m_Value(Op1)));
2681 // (~a) <u b
2682 if (Pred == ICmpInst::ICMP_ULT) {
2683 if (XorExpr.match(ICmpLHS))
2684 return L.match(Op1) && R.match(ICmpRHS) && S.match(ICmpLHS);
2685 }
2686 // b > u (~a)
2687 if (Pred == ICmpInst::ICMP_UGT) {
2688 if (XorExpr.match(ICmpRHS))
2689 return L.match(Op1) && R.match(ICmpLHS) && S.match(ICmpRHS);
2690 }
2691
2692 // Match special-case for increment-by-1.
2693 if (Pred == ICmpInst::ICMP_EQ) {
2694 // (a + 1) == 0
2695 // (1 + a) == 0
2696 if (AddExpr.match(ICmpLHS) && m_ZeroInt().match(ICmpRHS) &&
2697 (m_One().match(AddLHS) || m_One().match(AddRHS)))
2698 return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS);
2699 // 0 == (a + 1)
2700 // 0 == (1 + a)
2701 if (m_ZeroInt().match(ICmpLHS) && AddExpr.match(ICmpRHS) &&
2702 (m_One().match(AddLHS) || m_One().match(AddRHS)))
2703 return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
2704 }
2705
2706 return false;
2707 }
2708};
2709
2710/// Match an icmp instruction checking for unsigned overflow on addition.
2711///
2712/// S is matched to the addition whose result is being checked for overflow, and
2713/// L and R are matched to the LHS and RHS of S.
2714template <typename LHS_t, typename RHS_t, typename Sum_t>
2716m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) {
2718}
2719
2720template <typename Opnd_t> struct Argument_match {
2721 unsigned OpI;
2722 Opnd_t Val;
2723
2724 Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) {}
2725
2726 template <typename OpTy> bool match(OpTy *V) const {
2727 // FIXME: Should likely be switched to use `CallBase`.
2728 if (const auto *CI = dyn_cast<CallInst>(V))
2729 return Val.match(CI->getArgOperand(OpI));
2730 return false;
2731 }
2732};
2733
2734/// Match an argument.
2735template <unsigned OpI, typename Opnd_t>
2736inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
2737 return Argument_match<Opnd_t>(OpI, Op);
2738}
2739
2740/// Intrinsic matchers.
2742 unsigned ID;
2743
2745
2746 template <typename OpTy> bool match(OpTy *V) const {
2747 if (const auto *CI = dyn_cast<CallInst>(V))
2748 if (const auto *F = dyn_cast_or_null<Function>(CI->getCalledOperand()))
2749 return F->getIntrinsicID() == ID;
2750 return false;
2751 }
2752};
2753
2754/// Intrinsic matches are combinations of ID matchers, and argument
2755/// matchers. Higher arity matcher are defined recursively in terms of and-ing
2756/// them with lower arity matchers. Here's some convenient typedefs for up to
2757/// several arguments, and more can be added as needed
2758template <typename T0 = void, typename T1 = void, typename T2 = void,
2759 typename T3 = void, typename T4 = void, typename T5 = void,
2760 typename T6 = void, typename T7 = void, typename T8 = void,
2761 typename T9 = void, typename T10 = void>
2763template <typename T0> struct m_Intrinsic_Ty<T0> {
2765};
2766template <typename T0, typename T1> struct m_Intrinsic_Ty<T0, T1> {
2767 using Ty =
2769};
2770template <typename T0, typename T1, typename T2>
2775template <typename T0, typename T1, typename T2, typename T3>
2780
2781template <typename T0, typename T1, typename T2, typename T3, typename T4>
2786
2787template <typename T0, typename T1, typename T2, typename T3, typename T4,
2788 typename T5>
2793
2794/// Match intrinsic calls like this:
2795/// m_Intrinsic<Intrinsic::fabs>(m_Value(X))
2796template <Intrinsic::ID IntrID> inline IntrinsicID_match m_Intrinsic() {
2797 return IntrinsicID_match(IntrID);
2798}
2799
2800/// Matches MaskedLoad Intrinsic.
2801template <typename Opnd0, typename Opnd1, typename Opnd2>
2803m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
2804 return m_Intrinsic<Intrinsic::masked_load>(Op0, Op1, Op2);
2805}
2806
2807/// Matches MaskedStore Intrinsic.
2808template <typename Opnd0, typename Opnd1, typename Opnd2>
2810m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
2811 return m_Intrinsic<Intrinsic::masked_store>(Op0, Op1, Op2);
2812}
2813
2814/// Matches MaskedGather Intrinsic.
2815template <typename Opnd0, typename Opnd1, typename Opnd2>
2817m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
2818 return m_Intrinsic<Intrinsic::masked_gather>(Op0, Op1, Op2);
2819}
2820
2821template <Intrinsic::ID IntrID, typename T0>
2822inline typename m_Intrinsic_Ty<T0>::Ty m_Intrinsic(const T0 &Op0) {
2824}
2825
2826template <Intrinsic::ID IntrID, typename T0, typename T1>
2827inline typename m_Intrinsic_Ty<T0, T1>::Ty m_Intrinsic(const T0 &Op0,
2828 const T1 &Op1) {
2830}
2831
2832template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2>
2833inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty
2834m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) {
2835 return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2));
2836}
2837
2838template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2,
2839 typename T3>
2841m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
2842 return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3));
2843}
2844
2845template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2,
2846 typename T3, typename T4>
2848m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3,
2849 const T4 &Op4) {
2850 return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2, Op3),
2851 m_Argument<4>(Op4));
2852}
2853
2854template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2,
2855 typename T3, typename T4, typename T5>
2857m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3,
2858 const T4 &Op4, const T5 &Op5) {
2859 return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2, Op3, Op4),
2860 m_Argument<5>(Op5));
2861}
2862
2863// Helper intrinsic matching specializations.
2864template <typename Opnd0>
2865inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BitReverse(const Opnd0 &Op0) {
2867}
2868
2869template <typename Opnd0>
2870inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BSwap(const Opnd0 &Op0) {
2872}
2873
2874template <typename Opnd0>
2875inline typename m_Intrinsic_Ty<Opnd0>::Ty m_FAbs(const Opnd0 &Op0) {
2876 return m_Intrinsic<Intrinsic::fabs>(Op0);
2877}
2878
2879template <typename Opnd0>
2880inline typename m_Intrinsic_Ty<Opnd0>::Ty m_FCanonicalize(const Opnd0 &Op0) {
2882}
2883
2884template <typename Opnd0, typename Opnd1>
2885inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMinNum(const Opnd0 &Op0,
2886 const Opnd1 &Op1) {
2887 return m_Intrinsic<Intrinsic::minnum>(Op0, Op1);
2888}
2889
2890template <typename Opnd0, typename Opnd1>
2891inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMinimum(const Opnd0 &Op0,
2892 const Opnd1 &Op1) {
2893 return m_Intrinsic<Intrinsic::minimum>(Op0, Op1);
2894}
2895
2896template <typename Opnd0, typename Opnd1>
2898m_FMinimumNum(const Opnd0 &Op0, const Opnd1 &Op1) {
2899 return m_Intrinsic<Intrinsic::minimumnum>(Op0, Op1);
2900}
2901
2902template <typename Opnd0, typename Opnd1>
2903inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMaxNum(const Opnd0 &Op0,
2904 const Opnd1 &Op1) {
2905 return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1);
2906}
2907
2908template <typename Opnd0, typename Opnd1>
2909inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMaximum(const Opnd0 &Op0,
2910 const Opnd1 &Op1) {
2911 return m_Intrinsic<Intrinsic::maximum>(Op0, Op1);
2912}
2913
2914template <typename Opnd0, typename Opnd1>
2916m_FMaximumNum(const Opnd0 &Op0, const Opnd1 &Op1) {
2917 return m_Intrinsic<Intrinsic::maximumnum>(Op0, Op1);
2918}
2919
2920template <typename Opnd0, typename Opnd1, typename Opnd2>
2922m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
2923 return m_Intrinsic<Intrinsic::fshl>(Op0, Op1, Op2);
2924}
2925
2926template <typename Opnd0, typename Opnd1, typename Opnd2>
2928m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
2929 return m_Intrinsic<Intrinsic::fshr>(Op0, Op1, Op2);
2930}
2931
2932template <typename Opnd0>
2933inline typename m_Intrinsic_Ty<Opnd0>::Ty m_Sqrt(const Opnd0 &Op0) {
2934 return m_Intrinsic<Intrinsic::sqrt>(Op0);
2935}
2936
2937template <typename Opnd0, typename Opnd1>
2938inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_CopySign(const Opnd0 &Op0,
2939 const Opnd1 &Op1) {
2940 return m_Intrinsic<Intrinsic::copysign>(Op0, Op1);
2941}
2942
2943template <typename Opnd0>
2944inline typename m_Intrinsic_Ty<Opnd0>::Ty m_VecReverse(const Opnd0 &Op0) {
2946}
2947
2948template <typename Opnd0, typename Opnd1, typename Opnd2>
2950m_VectorInsert(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
2951 return m_Intrinsic<Intrinsic::vector_insert>(Op0, Op1, Op2);
2952}
2953
2954//===----------------------------------------------------------------------===//
2955// Matchers for two-operands operators with the operators in either order
2956//
2957
2958/// Matches a BinaryOperator with LHS and RHS in either order.
2959template <typename LHS, typename RHS>
2962}
2963
2964/// Matches an ICmp with a predicate over LHS and RHS in either order.
2965/// Swaps the predicate if operands are commuted.
2966template <typename LHS, typename RHS>
2968m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R) {
2970}
2971
2972template <typename LHS, typename RHS>
2977
2978/// Matches a specific opcode with LHS and RHS in either order.
2979template <typename LHS, typename RHS>
2981m_c_BinOp(unsigned Opcode, const LHS &L, const RHS &R) {
2982 return SpecificBinaryOp_match<LHS, RHS, true>(Opcode, L, R);
2983}
2984
2985/// Matches a Add with LHS and RHS in either order.
2986template <typename LHS, typename RHS>
2991
2992/// Matches a Mul with LHS and RHS in either order.
2993template <typename LHS, typename RHS>
2998
2999/// Matches an And with LHS and RHS in either order.
3000template <typename LHS, typename RHS>
3005
3006/// Matches an Or with LHS and RHS in either order.
3007template <typename LHS, typename RHS>
3012
3013/// Matches an Xor with LHS and RHS in either order.
3014template <typename LHS, typename RHS>
3019
3020/// Matches a 'Neg' as 'sub 0, V'.
3021template <typename ValTy>
3022inline BinaryOp_match<cst_pred_ty<is_zero_int>, ValTy, Instruction::Sub>
3023m_Neg(const ValTy &V) {
3024 return m_Sub(m_ZeroInt(), V);
3025}
3026
3027/// Matches a 'Neg' as 'sub nsw 0, V'.
3028template <typename ValTy>
3030 Instruction::Sub,
3032m_NSWNeg(const ValTy &V) {
3033 return m_NSWSub(m_ZeroInt(), V);
3034}
3035
3036/// Matches an SMin with LHS and RHS in either order.
3037template <typename LHS, typename RHS>
3039m_c_SMin(const LHS &L, const RHS &R) {
3041}
3042/// Matches an SMax with LHS and RHS in either order.
3043template <typename LHS, typename RHS>
3045m_c_SMax(const LHS &L, const RHS &R) {
3047}
3048/// Matches a UMin with LHS and RHS in either order.
3049template <typename LHS, typename RHS>
3051m_c_UMin(const LHS &L, const RHS &R) {
3053}
3054/// Matches a UMax with LHS and RHS in either order.
3055template <typename LHS, typename RHS>
3057m_c_UMax(const LHS &L, const RHS &R) {
3059}
3060
3061template <typename LHS, typename RHS>
3062inline match_combine_or<
3067m_c_MaxOrMin(const LHS &L, const RHS &R) {
3068 return m_CombineOr(m_CombineOr(m_c_SMax(L, R), m_c_SMin(L, R)),
3069 m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R)));
3070}
3071
3072template <Intrinsic::ID IntrID, typename T0, typename T1>
3075m_c_Intrinsic(const T0 &Op0, const T1 &Op1) {
3076 return m_CombineOr(m_Intrinsic<IntrID>(Op0, Op1),
3077 m_Intrinsic<IntrID>(Op1, Op0));
3078}
3079
3080/// Matches FAdd with LHS and RHS in either order.
3081template <typename LHS, typename RHS>
3083m_c_FAdd(const LHS &L, const RHS &R) {
3085}
3086
3087/// Matches FMul with LHS and RHS in either order.
3088template <typename LHS, typename RHS>
3090m_c_FMul(const LHS &L, const RHS &R) {
3092}
3093
3094template <typename Opnd_t> struct Signum_match {
3095 Opnd_t Val;
3096 Signum_match(const Opnd_t &V) : Val(V) {}
3097
3098 template <typename OpTy> bool match(OpTy *V) const {
3099 unsigned TypeSize = V->getType()->getScalarSizeInBits();
3100 if (TypeSize == 0)
3101 return false;
3102
3103 unsigned ShiftWidth = TypeSize - 1;
3104 Value *Op;
3105
3106 // This is the representation of signum we match:
3107 //
3108 // signum(x) == (x >> 63) | (-x >>u 63)
3109 //
3110 // An i1 value is its own signum, so it's correct to match
3111 //
3112 // signum(x) == (x >> 0) | (-x >>u 0)
3113 //
3114 // for i1 values.
3115
3116 auto LHS = m_AShr(m_Value(Op), m_SpecificInt(ShiftWidth));
3117 auto RHS = m_LShr(m_Neg(m_Deferred(Op)), m_SpecificInt(ShiftWidth));
3118 auto Signum = m_c_Or(LHS, RHS);
3119
3120 return Signum.match(V) && Val.match(Op);
3121 }
3122};
3123
3124/// Matches a signum pattern.
3125///
3126/// signum(x) =
3127/// x > 0 -> 1
3128/// x == 0 -> 0
3129/// x < 0 -> -1
3130template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) {
3131 return Signum_match<Val_t>(V);
3132}
3133
3134template <int Ind, typename Opnd_t> struct ExtractValue_match {
3135 Opnd_t Val;
3136 ExtractValue_match(const Opnd_t &V) : Val(V) {}
3137
3138 template <typename OpTy> bool match(OpTy *V) const {
3139 if (auto *I = dyn_cast<ExtractValueInst>(V)) {
3140 // If Ind is -1, don't inspect indices
3141 if (Ind != -1 &&
3142 !(I->getNumIndices() == 1 && I->getIndices()[0] == (unsigned)Ind))
3143 return false;
3144 return Val.match(I->getAggregateOperand());
3145 }
3146 return false;
3147 }
3148};
3149
3150/// Match a single index ExtractValue instruction.
3151/// For example m_ExtractValue<1>(...)
3152template <int Ind, typename Val_t>
3156
3157/// Match an ExtractValue instruction with any index.
3158/// For example m_ExtractValue(...)
3159template <typename Val_t>
3160inline ExtractValue_match<-1, Val_t> m_ExtractValue(const Val_t &V) {
3161 return ExtractValue_match<-1, Val_t>(V);
3162}
3163
3164/// Matcher for a single index InsertValue instruction.
3165template <int Ind, typename T0, typename T1> struct InsertValue_match {
3168
3169 InsertValue_match(const T0 &Op0, const T1 &Op1) : Op0(Op0), Op1(Op1) {}
3170
3171 template <typename OpTy> bool match(OpTy *V) const {
3172 if (auto *I = dyn_cast<InsertValueInst>(V)) {
3173 return Op0.match(I->getOperand(0)) && Op1.match(I->getOperand(1)) &&
3174 I->getNumIndices() == 1 && Ind == I->getIndices()[0];
3175 }
3176 return false;
3177 }
3178};
3179
3180/// Matches a single index InsertValue instruction.
3181template <int Ind, typename Val_t, typename Elt_t>
3183 const Elt_t &Elt) {
3184 return InsertValue_match<Ind, Val_t, Elt_t>(Val, Elt);
3185}
3186
3187/// Matches a call to `llvm.vscale()`.
3189
3190template <typename Opnd0, typename Opnd1>
3192m_Interleave2(const Opnd0 &Op0, const Opnd1 &Op1) {
3194}
3195
3196template <typename Opnd>
3200
3201template <typename LHS, typename RHS, unsigned Opcode, bool Commutable = false>
3205
3206 LogicalOp_match(const LHS &L, const RHS &R) : L(L), R(R) {}
3207
3208 template <typename T> bool match(T *V) const {
3209 auto *I = dyn_cast<Instruction>(V);
3210 if (!I || !I->getType()->isIntOrIntVectorTy(1))
3211 return false;
3212
3213 if (I->getOpcode() == Opcode) {
3214 auto *Op0 = I->getOperand(0);
3215 auto *Op1 = I->getOperand(1);
3216 return (L.match(Op0) && R.match(Op1)) ||
3217 (Commutable && L.match(Op1) && R.match(Op0));
3218 }
3219
3220 if (auto *Select = dyn_cast<SelectInst>(I)) {
3221 auto *Cond = Select->getCondition();
3222 auto *TVal = Select->getTrueValue();
3223 auto *FVal = Select->getFalseValue();
3224
3225 // Don't match a scalar select of bool vectors.
3226 // Transforms expect a single type for operands if this matches.
3227 if (Cond->getType() != Select->getType())
3228 return false;
3229
3230 if (Opcode == Instruction::And) {
3231 auto *C = dyn_cast<Constant>(FVal);
3232 if (C && C->isNullValue())
3233 return (L.match(Cond) && R.match(TVal)) ||
3234 (Commutable && L.match(TVal) && R.match(Cond));
3235 } else {
3236 assert(Opcode == Instruction::Or);
3237 auto *C = dyn_cast<Constant>(TVal);
3238 if (C && C->isOneValue())
3239 return (L.match(Cond) && R.match(FVal)) ||
3240 (Commutable && L.match(FVal) && R.match(Cond));
3241 }
3242 }
3243
3244 return false;
3245 }
3246};
3247
3248/// Matches L && R either in the form of L & R or L ? R : false.
3249/// Note that the latter form is poison-blocking.
3250template <typename LHS, typename RHS>
3255
3256/// Matches L && R where L and R are arbitrary values.
3257inline auto m_LogicalAnd() { return m_LogicalAnd(m_Value(), m_Value()); }
3258
3259/// Matches L && R with LHS and RHS in either order.
3260template <typename LHS, typename RHS>
3262m_c_LogicalAnd(const LHS &L, const RHS &R) {
3264}
3265
3266/// Matches L || R either in the form of L | R or L ? true : R.
3267/// Note that the latter form is poison-blocking.
3268template <typename LHS, typename RHS>
3273
3274/// Matches L || R where L and R are arbitrary values.
3275inline auto m_LogicalOr() { return m_LogicalOr(m_Value(), m_Value()); }
3276
3277/// Matches L || R with LHS and RHS in either order.
3278template <typename LHS, typename RHS>
3280m_c_LogicalOr(const LHS &L, const RHS &R) {
3282}
3283
3284/// Matches either L && R or L || R,
3285/// either one being in the either binary or logical form.
3286/// Note that the latter form is poison-blocking.
3287template <typename LHS, typename RHS, bool Commutable = false>
3293
3294/// Matches either L && R or L || R where L and R are arbitrary values.
3295inline auto m_LogicalOp() { return m_LogicalOp(m_Value(), m_Value()); }
3296
3297/// Matches either L && R or L || R with LHS and RHS in either order.
3298template <typename LHS, typename RHS>
3299inline auto m_c_LogicalOp(const LHS &L, const RHS &R) {
3300 return m_LogicalOp<LHS, RHS, /*Commutable=*/true>(L, R);
3301}
3302
3303} // end namespace PatternMatch
3304} // end namespace llvm
3305
3306#endif // LLVM_IR_PATTERNMATCH_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static constexpr unsigned long long mask(BlockVerifier::State S)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Hexagon Common GEP
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
#define T
#define T1
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
#define P(N)
const SmallVectorImpl< MachineOperand > & Cond
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1540
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1512
static bool isSameValue(const APInt &I1, const APInt &I2)
Determine if two APInts have the same value, after zero-extending one of them (if needed!...
Definition APInt.h:553
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_SLT
signed less than
Definition InstrTypes.h:705
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:706
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:682
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
Definition InstrTypes.h:691
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:680
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:681
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:700
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:699
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:703
@ FCMP_ULT
1 1 0 0 True if unordered or less than
Definition InstrTypes.h:690
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:701
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
Definition InstrTypes.h:688
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:683
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:704
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:702
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Definition InstrTypes.h:689
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
static LLVM_ABI CmpPredicate get(const CmpInst *Cmp)
Do a ICmpInst::getCmpPredicate() or CmpInst::getPredicate(), as appropriate.
static LLVM_ABI CmpPredicate getSwapped(CmpPredicate P)
Get the swapped predicate of a CmpPredicate.
Base class for aggregate constants (with operands).
Definition Constants.h:408
A constant value that is initialized with an expression using other constant values.
Definition Constants.h:1120
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:277
This is the shared class of boolean and integer constants.
Definition Constants.h:87
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
bool isBitwiseLogicOp() const
Return true if this is and/or/xor.
bool isShift() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
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.
Definition Type.h:45
'undef' values are things that do not have specified contents.
Definition Constants.h:1420
LLVM Value Representation.
Definition Value.h:75
Base class of all SIMD vector types.
Represents an op.with.overflow intrinsic.
An efficient, type-erasing, non-owning reference to a callable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
TwoOps_match< ValueOpTy, PointerOpTy, Instruction::Store > m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp)
Matches StoreInst.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
Matches GEP with i8 source element type.
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
ShiftLike_match< LHS, Instruction::LShr > m_LShrOrSelf(const LHS &L, uint64_t &R)
Matches lshr L, ConstShAmt or L itself (R will be set to zero in this case).
BinaryOp_match< cst_pred_ty< is_all_ones, false >, ValTy, Instruction::Xor, true > m_NotForbidPoison(const ValTy &V)
MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > m_UnordFMin(const LHS &L, const RHS &R)
Match an 'unordered' floating point minimum function.
PtrToIntSameSize_match< OpTy > m_PtrToIntSameSize(const DataLayout &DL, const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
m_Intrinsic_Ty< Opnd0 >::Ty m_FCanonicalize(const Opnd0 &Op0)
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)
Matches FMul with LHS and RHS in either order.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
auto m_PtrToIntOrAddr(const OpTy &Op)
Matches PtrToInt or PtrToAddr.
cstfp_pred_ty< is_inf > m_Inf()
Match a positive or negative infinity FP constant.
m_Intrinsic_Ty< Opnd0 >::Ty m_BitReverse(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedStore Intrinsic.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap, true > m_c_NSWAdd(const LHS &L, const RHS &R)
BinaryOp_match< cstfp_pred_ty< is_any_zero_fp >, RHS, Instruction::FSub > m_FNegNSZ(const RHS &X)
Match 'fneg X' as 'fsub +-0.0, X'.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, CastInst >, OpTy > m_CastOrSelf(const OpTy &Op)
Matches any cast or self. Used to ignore casts.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
AllowReassoc_match< T > m_AllowReassoc(const T &SubPattern)
OneOps_match< OpTy, Instruction::Freeze > m_Freeze(const OpTy &Op)
Matches FreezeInst.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
ap_match< APFloat > m_APFloatForbidPoison(const APFloat *&Res)
Match APFloat while forbidding poison in splat vector constants.
cst_pred_ty< is_power2_or_zero > m_Power2OrZero()
Match an integer or vector of 0 or power-of-2 values.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
br_match m_UnconditionalBr(BasicBlock *&Succ)
CastOperator_match< OpTy, Instruction::PtrToAddr > m_PtrToAddr(const OpTy &Op)
Matches PtrToAddr.
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
cst_pred_ty< is_shifted_mask > m_ShiftedMask()
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstval_pred_ty< Predicate, ConstantInt, AllowPoison > cst_pred_ty
specialization of cstval_pred_ty for ConstantInt
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMaxNum(const Opnd0 &Op0, const Opnd1 &Op1)
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
auto m_c_XorLike(const LHS &L, const RHS &R)
Match either (xor L, R), (xor R, L) or (sub nuw R, L) iff R.isMask() Only commutative matcher as the ...
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedLoad Intrinsic.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
cstfp_pred_ty< is_finite > m_Finite()
Match a finite FP constant, i.e.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
auto m_LogicalOp(const LHS &L, const RHS &R)
Matches either L && R or L || R, either one being in the either binary or logical form.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
IntrinsicID_match m_VScale()
Matches a call to llvm.vscale().
cstfp_pred_ty< is_neg_zero_fp > m_NegZeroFP()
Match a floating-point negative zero.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMinimum(const Opnd0 &Op0, const Opnd1 &Op1)
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
InsertValue_match< Ind, Val_t, Elt_t > m_InsertValue(const Val_t &Val, const Elt_t &Elt)
Matches a single index InsertValue instruction.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_Interleave2(const Opnd0 &Op0, const Opnd1 &Op1)
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
cst_pred_ty< is_any_apint > m_AnyIntegralConstant()
Match an integer or vector with any integral constant.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMaximum(const Opnd0 &Op0, const Opnd1 &Op1)
CastInst_match< OpTy, FPToUIInst > m_FPToUI(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_Sqrt(const Opnd0 &Op0)
ShiftLike_match< LHS, Instruction::Shl > m_ShlOrSelf(const LHS &L, uint64_t &R)
Matches shl L, ConstShAmt or L itself (R will be set to zero in this case).
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
SpecificCmpClass_match< LHS, RHS, CmpInst > m_SpecificCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
match_combine_or< typename m_Intrinsic_Ty< T0, T1 >::Ty, typename m_Intrinsic_Ty< T1, T0 >::Ty > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
match_combine_or< match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > >, OpTy > m_ZExtOrSExtOrSelf(const OpTy &Op)
OneUse_match< T > m_OneUse(const T &SubPattern)
NNegZExt_match< OpTy > m_NNegZExt(const OpTy &Op)
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > m_c_SMin(const LHS &L, const RHS &R)
Matches an SMin with LHS and RHS in either order.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
Splat_match< T > m_ConstantSplat(const T &SubPattern)
Match a constant splat. TODO: Extend this to non-constant splats.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
specific_bbval m_SpecificBB(BasicBlock *BB)
Match a specific basic block value.
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true > m_c_UMax(const LHS &L, const RHS &R)
Matches a UMax with LHS and RHS in either order.
auto m_GEP(const OperandTypes &...Ops)
Matches GetElementPtrInst.
ap_match< APInt > m_APIntForbidPoison(const APInt *&Res)
Match APInt while forbidding poison in splat vector constants.
cst_pred_ty< is_strictlypositive > m_StrictlyPositive()
Match an integer or vector of strictly positive values.
ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)
Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
class_match< ConstantFP > m_ConstantFP()
Match an arbitrary ConstantFP and ignore it.
cstfp_pred_ty< is_nonnan > m_NonNaN()
Match a non-NaN FP constant.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
cstfp_pred_ty< is_non_zero_not_denormal_fp > m_NonZeroNotDenormalFP()
Match a floating-point non-zero that is not a denormal.
cst_pred_ty< is_all_ones, false > m_AllOnesForbidPoison()
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
BinOpPred_match< LHS, RHS, is_bitwiselogic_op, true > m_c_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations in either order.
class_match< UndefValue > m_UndefValue()
Match an arbitrary UndefValue constant.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMaximumNum(const Opnd0 &Op0, const Opnd1 &Op1)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
cst_pred_ty< is_negated_power2_or_zero > m_NegatedPower2OrZero()
Match a integer or vector negated power-of-2.
auto m_c_LogicalOp(const LHS &L, const RHS &R)
Matches either L && R or L || R with LHS and RHS in either order.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
ShiftLike_match< LHS, Instruction::AShr > m_AShrOrSelf(const LHS &L, uint64_t &R)
Matches ashr L, ConstShAmt or L itself (R will be set to zero in this case).
cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)
Match an integer or vector where CheckFn(ele) for each element is true.
cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()
Match an integer or vector with only the low bit(s) set.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMinimumNum(const Opnd0 &Op0, const Opnd1 &Op1)
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
DisjointOr_match< LHS, RHS, true > m_c_DisjointOr(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > m_c_UMin(const LHS &L, const RHS &R)
Matches a UMin with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, FCmpInst > m_SpecificFCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedGather Intrinsic.
CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true > m_c_SMax(const LHS &L, const RHS &R)
Matches an SMax with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > > > m_c_MaxOrMin(const LHS &L, const RHS &R)
MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > m_UnordFMax(const LHS &L, const RHS &R)
Match an 'unordered' floating point maximum function.
cstval_pred_ty< Predicate, ConstantFP, true > cstfp_pred_ty
specialization of cstval_pred_ty for ConstantFP
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
class_match< UnaryOperator > m_UnOp()
Match an arbitrary unary operation and ignore it.
CastInst_match< OpTy, FPToSIInst > m_FPToSI(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
cstfp_pred_ty< custom_checkfn< APFloat > > m_CheckedFp(function_ref< bool(const APFloat &)> CheckFn)
Match a float or vector where CheckFn(ele) for each element is true.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty > m_OrdFMax(const LHS &L, const RHS &R)
Match an 'ordered' floating point maximum function.
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap >, DisjointOr_match< LHS, RHS > > m_NSWAddLike(const LHS &L, const RHS &R)
Match either "add nsw" or "or disjoint".
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
Signum_match< Val_t > m_Signum(const Val_t &V)
Matches a signum pattern.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Argument_match< Opnd_t > m_Argument(const Opnd_t &Op)
Match an argument.
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
Exact_match< T > m_Exact(const T &SubPattern)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::FAdd, true > m_c_FAdd(const LHS &L, const RHS &R)
Matches FAdd with LHS and RHS in either order.
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
cstfp_pred_ty< is_non_zero_fp > m_NonZeroFP()
Match a floating-point non-zero.
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty > m_OrdFMin(const LHS &L, const RHS &R)
Match an 'ordered' floating point minimum function.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
ThreeOps_match< Cond, constantint_match< L >, constantint_match< R >, Instruction::Select > m_SelectCst(const Cond &C)
This matches a select of two constants, e.g.: m_SelectCst<-1, 0>(m_Value(V))
BinaryOp_match< LHS, RHS, Instruction::FRem > m_FRem(const LHS &L, const RHS &R)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMinNum(const Opnd0 &Op0, const Opnd1 &Op1)
cst_pred_ty< is_nonpositive > m_NonPositive()
Match an integer or vector of non-positive values.
cstfp_pred_ty< is_nan > m_NaN()
Match an arbitrary NaN constant.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap >, DisjointOr_match< LHS, RHS > > m_NUWAddLike(const LHS &L, const RHS &R)
Match either "add nuw" or "or disjoint".
CastOperator_match< OpTy, Instruction::IntToPtr > m_IntToPtr(const OpTy &Op)
Matches IntToPtr.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op > m_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations.
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
SpecificCmpClass_match< LHS, RHS, ICmpInst, true > m_c_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_VectorInsert(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
MatchFunctor< Val, Pattern > match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
match_combine_or< match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, TruncInst > >, OpTy > m_ZExtOrTruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
cstfp_pred_ty< is_noninf > m_NonInf()
Match a non-infinity FP constant, i.e.
m_Intrinsic_Ty< Opnd >::Ty m_Deinterleave2(const Opnd &Op)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
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:1725
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:71
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1758
AllowReassoc_match(const SubPattern_t &SP)
AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS)
Matches instructions with Opcode and any number of operands.
std::enable_if_t< Idx==Last, bool > match_operands(const Instruction *I) const
std::enable_if_t< Idx !=Last, bool > match_operands(const Instruction *I) const
std::tuple< OperandTypes... > Operands
AnyOps_match(const OperandTypes &...Ops)
Argument_match(unsigned OpIdx, const Opnd_t &V)
BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS)
BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS)
bool match(unsigned Opc, OpTy *V) const
CastInst_match(const Op_t &OpMatch)
CmpClass_match(CmpPredicate &Pred, const LHS_t &LHS, const RHS_t &RHS)
CmpClass_match(const LHS_t &LHS, const RHS_t &RHS)
DisjointOr_match(const LHS &L, const RHS &R)
Exact_match(const SubPattern_t &SP)
Matcher for a single index InsertValue instruction.
InsertValue_match(const T0 &Op0, const T1 &Op1)
IntrinsicID_match(Intrinsic::ID IntrID)
LogicalOp_match(const LHS &L, const RHS &R)
MaxMin_match(const LHS_t &LHS, const RHS_t &RHS)
NNegZExt_match(const Op_t &OpMatch)
Matches instructions with Opcode and three operands.
OneUse_match(const SubPattern_t &SP)
OverflowingBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS)
PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
PtrToIntSameSize_match(const DataLayout &DL, const Op_t &OpMatch)
ShiftLike_match(const LHS_t &LHS, uint64_t &RHS)
Shuffle_match(const T0 &Op1, const T1 &Op2, const T2 &Mask)
SpecificBinaryOp_match(unsigned Opcode, const LHS_t &LHS, const RHS_t &RHS)
SpecificCmpClass_match(CmpPredicate Pred, const LHS_t &LHS, const RHS_t &RHS)
Splat_match(const SubPattern_t &SP)
Matches instructions with Opcode and three operands.
ThreeOps_match(const T0 &Op1, const T1 &Op2, const T2 &Op3)
Matches instructions with Opcode and three operands.
TwoOps_match(const T0 &Op1, const T1 &Op2)
UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S)
XorLike_match(const LHS &L, const RHS &R)
ap_match(const APTy *&Res, bool AllowPoison)
std::conditional_t< std::is_same_v< APTy, APInt >, ConstantInt, ConstantFP > ConstantTy
This helper class is used to match scalar and vector constants that satisfy a specified predicate,...
This helper class is used to match scalar and vector constants that satisfy a specified predicate,...
Check whether the value has the given Class and matches the nested pattern.
bind_and_match_ty(Class *&V, const MatchTy &Match)
bool match(ITy *V) const
bool match(OpTy *V) const
br_match(BasicBlock *&Succ)
brc_match(const Cond_t &C, const TrueBlock_t &t, const FalseBlock_t &f)
This helper class is used to match constant scalars, vector splats, and fixed width vectors that sati...
bool isValue(const APTy &C) const
function_ref< bool(const APTy &)> CheckFn
Stores a reference to the Value *, not the Value * itself, thus can be used in commutative matchers.
bool match(ITy *const V) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APFloat &C) const
bool isOpType(unsigned Opcode) const
bool isValue(const APFloat &C) const
bool isValue(const APFloat &C) const
bool isOpType(unsigned Opcode) const
bool isValue(const APFloat &C) const
bool isOpType(unsigned Opcode) const
bool isOpType(unsigned Opcode) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APFloat &C) const
bool isValue(const APFloat &C) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APFloat &C) const
bool isValue(const APFloat &C) const
bool isValue(const APFloat &C) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APFloat &C) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isOpType(unsigned Opcode) const
bool isOpType(unsigned Opcode) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool isValue(const APInt &C) const
bool match(ITy *V) const
match_combine_and< typename m_Intrinsic_Ty< T0, T1, T2, T3, T4 >::Ty, Argument_match< T5 > > Ty
match_combine_and< typename m_Intrinsic_Ty< T0, T1, T2, T3 >::Ty, Argument_match< T4 > > Ty
match_combine_and< typename m_Intrinsic_Ty< T0, T1, T2 >::Ty, Argument_match< T3 > > Ty
match_combine_and< typename m_Intrinsic_Ty< T0, T1 >::Ty, Argument_match< T2 > > Ty
match_combine_and< typename m_Intrinsic_Ty< T0 >::Ty, Argument_match< T1 > > Ty
match_combine_and< IntrinsicID_match, Argument_match< T0 > > Ty
Intrinsic matches are combinations of ID matchers, and argument matchers.
ArrayRef< int > & MaskRef
m_Mask(ArrayRef< int > &MaskRef)
bool match(ArrayRef< int > Mask) const
bool match(ArrayRef< int > Mask) const
m_SpecificMask(ArrayRef< int > Val)
bool match(ArrayRef< int > Mask) const
bool match(ArrayRef< int > Mask) const
match_combine_and(const LTy &Left, const RTy &Right)
match_combine_or(const LTy &Left, const RTy &Right)
Helper class for identifying ordered max predicates.
static bool match(FCmpInst::Predicate Pred)
Helper class for identifying ordered min predicates.
static bool match(FCmpInst::Predicate Pred)
Helper class for identifying signed max predicates.
static bool match(ICmpInst::Predicate Pred)
Helper class for identifying signed min predicates.
static bool match(ICmpInst::Predicate Pred)
Match a specified basic block value.
Match a specified floating point value or vector of all elements of that value.
Match a specified integer value or vector of all elements of that value.
Match a specified Value*.
Helper class for identifying unordered max predicates.
static bool match(FCmpInst::Predicate Pred)
Helper class for identifying unordered min predicates.
static bool match(FCmpInst::Predicate Pred)
Helper class for identifying unsigned max predicates.
static bool match(ICmpInst::Predicate Pred)
Helper class for identifying unsigned min predicates.
static bool match(ICmpInst::Predicate Pred)
static bool check(const Value *V)