diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/include/llvm/IR/PatternMatch.h | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/IR/PatternMatch.h')
-rw-r--r-- | contrib/libs/llvm12/include/llvm/IR/PatternMatch.h | 522 |
1 files changed, 261 insertions, 261 deletions
diff --git a/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h b/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h index a4aae7e731..2b6566a57b 100644 --- a/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h +++ b/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h @@ -95,29 +95,29 @@ inline class_match<BinaryOperator> m_BinOp() { /// Matches any compare instruction and ignore it. inline class_match<CmpInst> m_Cmp() { return class_match<CmpInst>(); } -/// Match an arbitrary undef constant. -inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } - -/// Match an arbitrary poison constant. -inline class_match<PoisonValue> m_Poison() { return class_match<PoisonValue>(); } - -/// Match an arbitrary Constant and ignore it. -inline class_match<Constant> m_Constant() { return class_match<Constant>(); } - +/// Match an arbitrary undef constant. +inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } + +/// Match an arbitrary poison constant. +inline class_match<PoisonValue> m_Poison() { return class_match<PoisonValue>(); } + +/// Match an arbitrary Constant and ignore it. +inline class_match<Constant> m_Constant() { return class_match<Constant>(); } + /// Match an arbitrary ConstantInt and ignore it. inline class_match<ConstantInt> m_ConstantInt() { return class_match<ConstantInt>(); } -/// Match an arbitrary ConstantFP and ignore it. -inline class_match<ConstantFP> m_ConstantFP() { - return class_match<ConstantFP>(); -} +/// Match an arbitrary ConstantFP and ignore it. +inline class_match<ConstantFP> m_ConstantFP() { + return class_match<ConstantFP>(); +} -/// Match an arbitrary ConstantExpr and ignore it. -inline class_match<ConstantExpr> m_ConstantExpr() { - return class_match<ConstantExpr>(); -} +/// Match an arbitrary ConstantExpr and ignore it. +inline class_match<ConstantExpr> m_ConstantExpr() { + return class_match<ConstantExpr>(); +} /// Match an arbitrary basic block value and ignore it. inline class_match<BasicBlock> m_BasicBlock() { @@ -355,33 +355,33 @@ template <typename Predicate> struct api_pred_ty : public Predicate { } }; -/// This helper class is used to match scalar and vector constants that -/// satisfy a specified predicate, and bind them to an APFloat. -/// Undefs are allowed in splat vector constants. -template <typename Predicate> struct apf_pred_ty : public Predicate { - const APFloat *&Res; - - apf_pred_ty(const APFloat *&R) : Res(R) {} - - template <typename ITy> bool match(ITy *V) { - if (const auto *CI = dyn_cast<ConstantFP>(V)) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } - if (V->getType()->isVectorTy()) - if (const auto *C = dyn_cast<Constant>(V)) - if (auto *CI = dyn_cast_or_null<ConstantFP>( - C->getSplatValue(/* AllowUndef */ true))) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } - - return false; - } -}; - +/// This helper class is used to match scalar and vector constants that +/// satisfy a specified predicate, and bind them to an APFloat. +/// Undefs are allowed in splat vector constants. +template <typename Predicate> struct apf_pred_ty : public Predicate { + const APFloat *&Res; + + apf_pred_ty(const APFloat *&R) : Res(R) {} + + template <typename ITy> bool match(ITy *V) { + if (const auto *CI = dyn_cast<ConstantFP>(V)) + if (this->isValue(CI->getValue())) { + Res = &CI->getValue(); + return true; + } + if (V->getType()->isVectorTy()) + if (const auto *C = dyn_cast<Constant>(V)) + if (auto *CI = dyn_cast_or_null<ConstantFP>( + C->getSplatValue(/* AllowUndef */ true))) + if (this->isValue(CI->getValue())) { + Res = &CI->getValue(); + return true; + } + + return false; + } +}; + /////////////////////////////////////////////////////////////////////////////// // // Encapsulate constant value queries for use in templated predicate matchers. @@ -602,15 +602,15 @@ inline cstfp_pred_ty<is_nan> m_NaN() { return cstfp_pred_ty<is_nan>(); } -struct is_nonnan { - bool isValue(const APFloat &C) { return !C.isNaN(); } -}; -/// Match a non-NaN FP constant. -/// For vectors, this includes constants with undefined elements. -inline cstfp_pred_ty<is_nonnan> m_NonNaN() { - return cstfp_pred_ty<is_nonnan>(); -} - +struct is_nonnan { + bool isValue(const APFloat &C) { return !C.isNaN(); } +}; +/// Match a non-NaN FP constant. +/// For vectors, this includes constants with undefined elements. +inline cstfp_pred_ty<is_nonnan> m_NonNaN() { + return cstfp_pred_ty<is_nonnan>(); +} + struct is_inf { bool isValue(const APFloat &C) { return C.isInfinity(); } }; @@ -620,37 +620,37 @@ inline cstfp_pred_ty<is_inf> m_Inf() { return cstfp_pred_ty<is_inf>(); } -struct is_noninf { - bool isValue(const APFloat &C) { return !C.isInfinity(); } -}; -/// Match a non-infinity FP constant, i.e. finite or NaN. -/// For vectors, this includes constants with undefined elements. -inline cstfp_pred_ty<is_noninf> m_NonInf() { - return cstfp_pred_ty<is_noninf>(); -} - -struct is_finite { - bool isValue(const APFloat &C) { return C.isFinite(); } -}; -/// Match a finite FP constant, i.e. not infinity or NaN. -/// For vectors, this includes constants with undefined elements. -inline cstfp_pred_ty<is_finite> m_Finite() { - return cstfp_pred_ty<is_finite>(); -} -inline apf_pred_ty<is_finite> m_Finite(const APFloat *&V) { return V; } - -struct is_finitenonzero { - bool isValue(const APFloat &C) { return C.isFiniteNonZero(); } -}; -/// Match a finite non-zero FP constant. -/// For vectors, this includes constants with undefined elements. -inline cstfp_pred_ty<is_finitenonzero> m_FiniteNonZero() { - return cstfp_pred_ty<is_finitenonzero>(); -} -inline apf_pred_ty<is_finitenonzero> m_FiniteNonZero(const APFloat *&V) { - return V; -} - +struct is_noninf { + bool isValue(const APFloat &C) { return !C.isInfinity(); } +}; +/// Match a non-infinity FP constant, i.e. finite or NaN. +/// For vectors, this includes constants with undefined elements. +inline cstfp_pred_ty<is_noninf> m_NonInf() { + return cstfp_pred_ty<is_noninf>(); +} + +struct is_finite { + bool isValue(const APFloat &C) { return C.isFinite(); } +}; +/// Match a finite FP constant, i.e. not infinity or NaN. +/// For vectors, this includes constants with undefined elements. +inline cstfp_pred_ty<is_finite> m_Finite() { + return cstfp_pred_ty<is_finite>(); +} +inline apf_pred_ty<is_finite> m_Finite(const APFloat *&V) { return V; } + +struct is_finitenonzero { + bool isValue(const APFloat &C) { return C.isFiniteNonZero(); } +}; +/// Match a finite non-zero FP constant. +/// For vectors, this includes constants with undefined elements. +inline cstfp_pred_ty<is_finitenonzero> m_FiniteNonZero() { + return cstfp_pred_ty<is_finitenonzero>(); +} +inline apf_pred_ty<is_finitenonzero> m_FiniteNonZero(const APFloat *&V) { + return V; +} + struct is_any_zero_fp { bool isValue(const APFloat &C) { return C.isZero(); } }; @@ -678,15 +678,15 @@ inline cstfp_pred_ty<is_neg_zero_fp> m_NegZeroFP() { return cstfp_pred_ty<is_neg_zero_fp>(); } -struct is_non_zero_fp { - bool isValue(const APFloat &C) { return C.isNonZero(); } -}; -/// Match a floating-point non-zero. -/// For vectors, this includes constants with undefined elements. -inline cstfp_pred_ty<is_non_zero_fp> m_NonZeroFP() { - return cstfp_pred_ty<is_non_zero_fp>(); -} - +struct is_non_zero_fp { + bool isValue(const APFloat &C) { return C.isNonZero(); } +}; +/// Match a floating-point non-zero. +/// For vectors, this includes constants with undefined elements. +inline cstfp_pred_ty<is_non_zero_fp> m_NonZeroFP() { + return cstfp_pred_ty<is_non_zero_fp>(); +} + /////////////////////////////////////////////////////////////////////////////// template <typename Class> struct bind_ty { @@ -716,38 +716,38 @@ inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; } /// Match a with overflow intrinsic, capturing it if we match. inline bind_ty<WithOverflowInst> m_WithOverflowInst(WithOverflowInst *&I) { return I; } -/// Match a Constant, capturing the value if we match. -inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } - +/// Match a Constant, capturing the value if we match. +inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } + /// Match a ConstantInt, capturing the value if we match. inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } /// Match a ConstantFP, capturing the value if we match. inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } -/// Match a ConstantExpr, capturing the value if we match. -inline bind_ty<ConstantExpr> m_ConstantExpr(ConstantExpr *&C) { return C; } - +/// Match a ConstantExpr, capturing the value if we match. +inline bind_ty<ConstantExpr> m_ConstantExpr(ConstantExpr *&C) { return C; } + /// Match a basic block value, capturing it if we match. inline bind_ty<BasicBlock> m_BasicBlock(BasicBlock *&V) { return V; } inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) { return V; } -/// Match an arbitrary immediate Constant and ignore it. -inline match_combine_and<class_match<Constant>, - match_unless<class_match<ConstantExpr>>> -m_ImmConstant() { - return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr())); -} - -/// Match an immediate Constant, capturing the value if we match. -inline match_combine_and<bind_ty<Constant>, - match_unless<class_match<ConstantExpr>>> -m_ImmConstant(Constant *&C) { - return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr())); -} - +/// Match an arbitrary immediate Constant and ignore it. +inline match_combine_and<class_match<Constant>, + match_unless<class_match<ConstantExpr>>> +m_ImmConstant() { + return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr())); +} + +/// Match an immediate Constant, capturing the value if we match. +inline match_combine_and<bind_ty<Constant>, + match_unless<class_match<ConstantExpr>>> +m_ImmConstant(Constant *&C) { + return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr())); +} + /// Match a specified Value*. struct specificval_ty { const Value *Val; @@ -818,7 +818,7 @@ struct bind_const_intval_ty { /// Match a specified integer value or vector of all elements of that /// value. -template <bool AllowUndefs> +template <bool AllowUndefs> struct specific_intval { APInt Val; @@ -828,7 +828,7 @@ struct specific_intval { const auto *CI = dyn_cast<ConstantInt>(V); if (!CI && V->getType()->isVectorTy()) if (const auto *C = dyn_cast<Constant>(V)) - CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowUndefs)); + CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowUndefs)); return CI && APInt::isSameValue(CI->getValue(), Val); } @@ -836,22 +836,22 @@ struct specific_intval { /// Match a specific integer value or vector with all elements equal to /// the value. -inline specific_intval<false> m_SpecificInt(APInt V) { - return specific_intval<false>(std::move(V)); +inline specific_intval<false> m_SpecificInt(APInt V) { + return specific_intval<false>(std::move(V)); } -inline specific_intval<false> m_SpecificInt(uint64_t V) { +inline specific_intval<false> m_SpecificInt(uint64_t V) { return m_SpecificInt(APInt(64, V)); } -inline specific_intval<true> m_SpecificIntAllowUndef(APInt V) { - return specific_intval<true>(std::move(V)); -} - -inline specific_intval<true> m_SpecificIntAllowUndef(uint64_t V) { - return m_SpecificIntAllowUndef(APInt(64, V)); -} - +inline specific_intval<true> m_SpecificIntAllowUndef(APInt V) { + return specific_intval<true>(std::move(V)); +} + +inline specific_intval<true> m_SpecificIntAllowUndef(uint64_t V) { + return m_SpecificIntAllowUndef(APInt(64, V)); +} + /// Match a ConstantInt and bind to its value. This does not match /// ConstantInts wider than 64-bits. inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; } @@ -1564,12 +1564,12 @@ inline CastClass_match<OpTy, Instruction::PtrToInt> m_PtrToInt(const OpTy &Op) { return CastClass_match<OpTy, Instruction::PtrToInt>(Op); } -/// Matches IntToPtr. -template <typename OpTy> -inline CastClass_match<OpTy, Instruction::IntToPtr> m_IntToPtr(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::IntToPtr>(Op); -} - +/// Matches IntToPtr. +template <typename OpTy> +inline CastClass_match<OpTy, Instruction::IntToPtr> m_IntToPtr(const OpTy &Op) { + return CastClass_match<OpTy, Instruction::IntToPtr>(Op); +} + /// Matches Trunc. template <typename OpTy> inline CastClass_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) { @@ -1718,17 +1718,17 @@ struct MaxMin_match { MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template <typename OpTy> bool match(OpTy *V) { - if (auto *II = dyn_cast<IntrinsicInst>(V)) { - Intrinsic::ID IID = II->getIntrinsicID(); - if ((IID == Intrinsic::smax && Pred_t::match(ICmpInst::ICMP_SGT)) || - (IID == Intrinsic::smin && Pred_t::match(ICmpInst::ICMP_SLT)) || - (IID == Intrinsic::umax && Pred_t::match(ICmpInst::ICMP_UGT)) || - (IID == Intrinsic::umin && Pred_t::match(ICmpInst::ICMP_ULT))) { - Value *LHS = II->getOperand(0), *RHS = II->getOperand(1); - return (L.match(LHS) && R.match(RHS)) || - (Commutable && L.match(RHS) && R.match(LHS)); - } - } + if (auto *II = dyn_cast<IntrinsicInst>(V)) { + Intrinsic::ID IID = II->getIntrinsicID(); + if ((IID == Intrinsic::smax && Pred_t::match(ICmpInst::ICMP_SGT)) || + (IID == Intrinsic::smin && Pred_t::match(ICmpInst::ICMP_SLT)) || + (IID == Intrinsic::umax && Pred_t::match(ICmpInst::ICMP_UGT)) || + (IID == Intrinsic::umin && Pred_t::match(ICmpInst::ICMP_ULT))) { + Value *LHS = II->getOperand(0), *RHS = II->getOperand(1); + return (L.match(LHS) && R.match(RHS)) || + (Commutable && L.match(RHS) && R.match(LHS)); + } + } // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". auto *SI = dyn_cast<SelectInst>(V); if (!SI) @@ -1836,17 +1836,17 @@ inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> m_UMin(const LHS &L, return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R); } -template <typename LHS, typename RHS> -inline 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) { - return m_CombineOr(m_CombineOr(m_SMax(L, R), m_SMin(L, R)), - m_CombineOr(m_UMax(L, R), m_UMin(L, R))); -} - +template <typename LHS, typename RHS> +inline 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) { + return m_CombineOr(m_CombineOr(m_SMax(L, R), m_SMin(L, R)), + m_CombineOr(m_UMax(L, R), m_UMin(L, R))); +} + /// Match an 'ordered' floating point maximum function. /// Floating point has one special value 'NaN'. Therefore, there is no total /// order. However, if we can ignore the 'NaN' value (for example, because of a @@ -2137,18 +2137,18 @@ inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMax(const Opnd0 &Op0, return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1); } -template <typename Opnd0, typename Opnd1, typename Opnd2> -inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty -m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) { - return m_Intrinsic<Intrinsic::fshl>(Op0, Op1, Op2); -} - -template <typename Opnd0, typename Opnd1, typename Opnd2> -inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty -m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) { - return m_Intrinsic<Intrinsic::fshr>(Op0, Op1, Op2); -} - +template <typename Opnd0, typename Opnd1, typename Opnd2> +inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty +m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) { + return m_Intrinsic<Intrinsic::fshl>(Op0, Op1, Op2); +} + +template <typename Opnd0, typename Opnd1, typename Opnd2> +inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty +m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) { + return m_Intrinsic<Intrinsic::fshr>(Op0, Op1, Op2); +} + //===----------------------------------------------------------------------===// // Matchers for two-operands operators with the operators in either order // @@ -2210,15 +2210,15 @@ m_Neg(const ValTy &V) { return m_Sub(m_ZeroInt(), V); } -/// Matches a 'Neg' as 'sub nsw 0, V'. -template <typename ValTy> -inline OverflowingBinaryOp_match<cst_pred_ty<is_zero_int>, ValTy, - Instruction::Sub, - OverflowingBinaryOperator::NoSignedWrap> -m_NSWNeg(const ValTy &V) { - return m_NSWSub(m_ZeroInt(), V); -} - +/// Matches a 'Neg' as 'sub nsw 0, V'. +template <typename ValTy> +inline OverflowingBinaryOp_match<cst_pred_ty<is_zero_int>, ValTy, + Instruction::Sub, + OverflowingBinaryOperator::NoSignedWrap> +m_NSWNeg(const ValTy &V) { + return m_NSWSub(m_ZeroInt(), V); +} + /// Matches a 'Not' as 'xor V, -1' or 'xor -1, V'. template <typename ValTy> inline BinaryOp_match<ValTy, cst_pred_ty<is_all_ones>, Instruction::Xor, true> @@ -2251,17 +2251,17 @@ m_c_UMax(const LHS &L, const RHS &R) { return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R); } -template <typename LHS, typename RHS> -inline 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) { - return m_CombineOr(m_CombineOr(m_c_SMax(L, R), m_c_SMin(L, R)), - m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R))); -} - +template <typename LHS, typename RHS> +inline 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) { + return m_CombineOr(m_CombineOr(m_c_SMax(L, R), m_c_SMin(L, R)), + m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R))); +} + /// Matches FAdd with LHS and RHS in either order. template <typename LHS, typename RHS> inline BinaryOp_match<LHS, RHS, Instruction::FAdd, true> @@ -2335,29 +2335,29 @@ inline ExtractValue_match<Ind, Val_t> m_ExtractValue(const Val_t &V) { return ExtractValue_match<Ind, Val_t>(V); } -/// Matcher for a single index InsertValue instruction. -template <int Ind, typename T0, typename T1> struct InsertValue_match { - T0 Op0; - T1 Op1; - - InsertValue_match(const T0 &Op0, const T1 &Op1) : Op0(Op0), Op1(Op1) {} - - template <typename OpTy> bool match(OpTy *V) { - if (auto *I = dyn_cast<InsertValueInst>(V)) { - return Op0.match(I->getOperand(0)) && Op1.match(I->getOperand(1)) && - I->getNumIndices() == 1 && Ind == I->getIndices()[0]; - } - return false; - } -}; - -/// Matches a single index InsertValue instruction. -template <int Ind, typename Val_t, typename Elt_t> -inline InsertValue_match<Ind, Val_t, Elt_t> m_InsertValue(const Val_t &Val, - const Elt_t &Elt) { - return InsertValue_match<Ind, Val_t, Elt_t>(Val, Elt); -} - +/// Matcher for a single index InsertValue instruction. +template <int Ind, typename T0, typename T1> struct InsertValue_match { + T0 Op0; + T1 Op1; + + InsertValue_match(const T0 &Op0, const T1 &Op1) : Op0(Op0), Op1(Op1) {} + + template <typename OpTy> bool match(OpTy *V) { + if (auto *I = dyn_cast<InsertValueInst>(V)) { + return Op0.match(I->getOperand(0)) && Op1.match(I->getOperand(1)) && + I->getNumIndices() == 1 && Ind == I->getIndices()[0]; + } + return false; + } +}; + +/// Matches a single index InsertValue instruction. +template <int Ind, typename Val_t, typename Elt_t> +inline InsertValue_match<Ind, Val_t, Elt_t> m_InsertValue(const Val_t &Val, + const Elt_t &Elt) { + return InsertValue_match<Ind, Val_t, Elt_t>(Val, Elt); +} + /// Matches patterns for `vscale`. This can either be a call to `llvm.vscale` or /// the constant expression /// `ptrtoint(gep <vscale x 1 x i8>, <vscale x 1 x i8>* null, i32 1>` @@ -2394,58 +2394,58 @@ inline VScaleVal_match m_VScale(const DataLayout &DL) { return VScaleVal_match(DL); } -template <typename LHS, typename RHS, unsigned Opcode> -struct LogicalOp_match { - LHS L; - RHS R; - - LogicalOp_match(const LHS &L, const RHS &R) : L(L), R(R) {} - - template <typename T> bool match(T *V) { - if (auto *I = dyn_cast<Instruction>(V)) { - if (!I->getType()->isIntOrIntVectorTy(1)) - return false; - - if (I->getOpcode() == Opcode && L.match(I->getOperand(0)) && - R.match(I->getOperand(1))) - return true; - - if (auto *SI = dyn_cast<SelectInst>(I)) { - if (Opcode == Instruction::And) { - if (const auto *C = dyn_cast<Constant>(SI->getFalseValue())) - if (C->isNullValue() && L.match(SI->getCondition()) && - R.match(SI->getTrueValue())) - return true; - } else { - assert(Opcode == Instruction::Or); - if (const auto *C = dyn_cast<Constant>(SI->getTrueValue())) - if (C->isOneValue() && L.match(SI->getCondition()) && - R.match(SI->getFalseValue())) - return true; - } - } - } - - return false; - } -}; - -/// Matches L && R either in the form of L & R or L ? R : false. -/// Note that the latter form is poison-blocking. -template <typename LHS, typename RHS> -inline LogicalOp_match<LHS, RHS, Instruction::And> -m_LogicalAnd(const LHS &L, const RHS &R) { - return LogicalOp_match<LHS, RHS, Instruction::And>(L, R); -} - -/// Matches L || R either in the form of L | R or L ? true : R. -/// Note that the latter form is poison-blocking. -template <typename LHS, typename RHS> -inline LogicalOp_match<LHS, RHS, Instruction::Or> -m_LogicalOr(const LHS &L, const RHS &R) { - return LogicalOp_match<LHS, RHS, Instruction::Or>(L, R); -} - +template <typename LHS, typename RHS, unsigned Opcode> +struct LogicalOp_match { + LHS L; + RHS R; + + LogicalOp_match(const LHS &L, const RHS &R) : L(L), R(R) {} + + template <typename T> bool match(T *V) { + if (auto *I = dyn_cast<Instruction>(V)) { + if (!I->getType()->isIntOrIntVectorTy(1)) + return false; + + if (I->getOpcode() == Opcode && L.match(I->getOperand(0)) && + R.match(I->getOperand(1))) + return true; + + if (auto *SI = dyn_cast<SelectInst>(I)) { + if (Opcode == Instruction::And) { + if (const auto *C = dyn_cast<Constant>(SI->getFalseValue())) + if (C->isNullValue() && L.match(SI->getCondition()) && + R.match(SI->getTrueValue())) + return true; + } else { + assert(Opcode == Instruction::Or); + if (const auto *C = dyn_cast<Constant>(SI->getTrueValue())) + if (C->isOneValue() && L.match(SI->getCondition()) && + R.match(SI->getFalseValue())) + return true; + } + } + } + + return false; + } +}; + +/// Matches L && R either in the form of L & R or L ? R : false. +/// Note that the latter form is poison-blocking. +template <typename LHS, typename RHS> +inline LogicalOp_match<LHS, RHS, Instruction::And> +m_LogicalAnd(const LHS &L, const RHS &R) { + return LogicalOp_match<LHS, RHS, Instruction::And>(L, R); +} + +/// Matches L || R either in the form of L | R or L ? true : R. +/// Note that the latter form is poison-blocking. +template <typename LHS, typename RHS> +inline LogicalOp_match<LHS, RHS, Instruction::Or> +m_LogicalOr(const LHS &L, const RHS &R) { + return LogicalOp_match<LHS, RHS, Instruction::Or>(L, R); +} + } // end namespace PatternMatch } // end namespace llvm |