diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-07-01 13:42:57 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-07-01 13:42:57 +0000 |
commit | a9fdb9fd3786eaa584b0656937bfaad31f47ace4 (patch) | |
tree | 0d20a449d40b6197f458741f0b4fcb05896bdc23 | |
parent | 77d2067677cfc16ef6a7934fc0c9d6cdf1d01376 (diff) | |
download | bcm5719-llvm-a9fdb9fd3786eaa584b0656937bfaad31f47ace4.tar.gz bcm5719-llvm-a9fdb9fd3786eaa584b0656937bfaad31f47ace4.zip |
[PatternMatch] allow undef elements in vectors with m_Neg
This is similar to the m_Not change from D44076.
llvm-svn: 336064
-rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 114 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/add.ll | 8 |
2 files changed, 50 insertions, 72 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 191aa958a98..aa502cf0ed7 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1220,33 +1220,6 @@ m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) { } //===----------------------------------------------------------------------===// -// Matchers for unary operators -// - -template <typename LHS_t> struct neg_match { - LHS_t L; - - neg_match(const LHS_t &LHS) : L(LHS) {} - - template <typename OpTy> bool match(OpTy *V) { - if (auto *O = dyn_cast<Operator>(V)) - if (O->getOpcode() == Instruction::Sub) - return matchIfNeg(O->getOperand(0), O->getOperand(1)); - return false; - } - -private: - bool matchIfNeg(Value *LHS, Value *RHS) { - return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) || - isa<ConstantAggregateZero>(LHS)) && - L.match(RHS); - } -}; - -/// Match an integer negate. -template <typename LHS> inline neg_match<LHS> m_Neg(const LHS &L) { return L; } - -//===----------------------------------------------------------------------===// // Matchers for control flow. // @@ -1632,46 +1605,6 @@ inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMax(const Opnd0 &Op0, return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1); } -template <typename Opnd_t> struct Signum_match { - Opnd_t Val; - Signum_match(const Opnd_t &V) : Val(V) {} - - template <typename OpTy> bool match(OpTy *V) { - unsigned TypeSize = V->getType()->getScalarSizeInBits(); - if (TypeSize == 0) - return false; - - unsigned ShiftWidth = TypeSize - 1; - Value *OpL = nullptr, *OpR = nullptr; - - // This is the representation of signum we match: - // - // signum(x) == (x >> 63) | (-x >>u 63) - // - // An i1 value is its own signum, so it's correct to match - // - // signum(x) == (x >> 0) | (-x >>u 0) - // - // for i1 values. - - auto LHS = m_AShr(m_Value(OpL), m_SpecificInt(ShiftWidth)); - auto RHS = m_LShr(m_Neg(m_Value(OpR)), m_SpecificInt(ShiftWidth)); - auto Signum = m_Or(LHS, RHS); - - return Signum.match(V) && OpL == OpR && Val.match(OpL); - } -}; - -/// Matches a signum pattern. -/// -/// signum(x) = -/// x > 0 -> 1 -/// x == 0 -> 0 -/// x < 0 -> -1 -template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) { - return Signum_match<Val_t>(V); -} - //===----------------------------------------------------------------------===// // Matchers for two-operands operators with the operators in either order // @@ -1726,6 +1659,13 @@ inline BinaryOp_match<LHS, RHS, Instruction::Xor, true> m_c_Xor(const LHS &L, return BinaryOp_match<LHS, RHS, Instruction::Xor, true>(L, R); } +/// Matches a 'Neg' as 'sub 0, V'. +template <typename ValTy> +inline BinaryOp_match<cst_pred_ty<is_zero_int>, ValTy, Instruction::Sub> +m_Neg(const ValTy &V) { + return m_Sub(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> @@ -1772,6 +1712,46 @@ m_c_FMul(const LHS &L, const RHS &R) { return BinaryOp_match<LHS, RHS, Instruction::FMul, true>(L, R); } +template <typename Opnd_t> struct Signum_match { + Opnd_t Val; + Signum_match(const Opnd_t &V) : Val(V) {} + + template <typename OpTy> bool match(OpTy *V) { + unsigned TypeSize = V->getType()->getScalarSizeInBits(); + if (TypeSize == 0) + return false; + + unsigned ShiftWidth = TypeSize - 1; + Value *OpL = nullptr, *OpR = nullptr; + + // This is the representation of signum we match: + // + // signum(x) == (x >> 63) | (-x >>u 63) + // + // An i1 value is its own signum, so it's correct to match + // + // signum(x) == (x >> 0) | (-x >>u 0) + // + // for i1 values. + + auto LHS = m_AShr(m_Value(OpL), m_SpecificInt(ShiftWidth)); + auto RHS = m_LShr(m_Neg(m_Value(OpR)), m_SpecificInt(ShiftWidth)); + auto Signum = m_Or(LHS, RHS); + + return Signum.match(V) && OpL == OpR && Val.match(OpL); + } +}; + +/// Matches a signum pattern. +/// +/// signum(x) = +/// x > 0 -> 1 +/// x == 0 -> 0 +/// x < 0 -> -1 +template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) { + return Signum_match<Val_t>(V); +} + } // end namespace PatternMatch } // end namespace llvm diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index c673a77e9e5..9685b011304 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -121,8 +121,7 @@ define i32 @test5(i32 %A, i32 %B) { define <2 x i8> @neg_op0_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @neg_op0_vec_undef_elt( -; CHECK-NEXT: [[NEGA:%.*]] = sub <2 x i8> <i8 0, i8 undef>, [[A:%.*]] -; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[NEGA]], [[B:%.*]] +; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]] ; CHECK-NEXT: ret <2 x i8> [[R]] ; %nega = sub <2 x i8> <i8 0, i8 undef>, %a @@ -132,9 +131,8 @@ define <2 x i8> @neg_op0_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) { define <2 x i8> @neg_neg_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @neg_neg_vec_undef_elt( -; CHECK-NEXT: [[NEGA:%.*]] = sub <2 x i8> <i8 undef, i8 0>, [[A:%.*]] -; CHECK-NEXT: [[NEGB:%.*]] = sub <2 x i8> <i8 undef, i8 0>, [[B:%.*]] -; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[NEGA]], [[NEGB]] +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]] ; CHECK-NEXT: ret <2 x i8> [[R]] ; %nega = sub <2 x i8> <i8 undef, i8 0>, %a |