mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-26 14:16:12 +00:00
[PatternMatch] allow undef elements in vectors with m_Neg
This is similar to the m_Not change from D44076. llvm-svn: 336064
This commit is contained in:
parent
1b899b8559
commit
d0b447b76b
@ -1219,33 +1219,6 @@ m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) {
|
||||
return StoreClass_match<ValueOpTy, PointerOpTy>(ValueOp, 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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user