[PatternMatch] define m_FNeg using m_FSub

Using cstfp_pred_ty in the definition allows us to match vectors with undef elements.

This replicates the change for m_Not from D44076 / rL326823 and continues
towards making all pattern matchers allow undef elements in vectors.

llvm-svn: 329303
This commit is contained in:
Sanjay Patel 2018-04-05 15:36:55 +00:00
parent 2ce9274da6
commit 2204520e49
5 changed files with 16 additions and 45 deletions

View File

@ -621,6 +621,13 @@ inline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L,
return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R); return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
} }
/// Match 'fneg X' as 'fsub -0.0, X'.
template <typename RHS>
inline BinaryOp_match<cstfp_pred_ty<is_neg_zero_fp>, RHS, Instruction::FSub>
m_FNeg(const RHS &X) {
return m_FSub(m_NegZeroFP(), X);
}
template <typename LHS, typename RHS> template <typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L, inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
const RHS &R) { const RHS &R) {
@ -1181,31 +1188,6 @@ private:
/// Match an integer negate. /// Match an integer negate.
template <typename LHS> inline neg_match<LHS> m_Neg(const LHS &L) { return L; } template <typename LHS> inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
template <typename LHS_t> struct fneg_match {
LHS_t L;
fneg_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::FSub)
return matchIfFNeg(O->getOperand(0), O->getOperand(1));
return false;
}
private:
bool matchIfFNeg(Value *LHS, Value *RHS) {
if (const auto *C = dyn_cast<Constant>(LHS))
return C->isNegativeZeroValue() && L.match(RHS);
return false;
}
};
/// Match a floating point negate.
template <typename LHS> inline fneg_match<LHS> m_FNeg(const LHS &L) {
return L;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Matchers for control flow. // Matchers for control flow.
// //

View File

@ -68,8 +68,7 @@ define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
define <2 x i1> @fneg_constant_swap_pred_vec_undef(<2 x float> %x) { define <2 x i1> @fneg_constant_swap_pred_vec_undef(<2 x float> %x) {
; CHECK-LABEL: @fneg_constant_swap_pred_vec_undef( ; CHECK-LABEL: @fneg_constant_swap_pred_vec_undef(
; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[NEG]], <float 1.000000e+00, float 2.000000e+00>
; CHECK-NEXT: ret <2 x i1> [[CMP]] ; CHECK-NEXT: ret <2 x i1> [[CMP]]
; ;
%neg = fsub <2 x float> <float undef, float -0.0>, %x %neg = fsub <2 x float> <float undef, float -0.0>, %x
@ -101,9 +100,7 @@ define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
define <2 x i1> @fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) { define <2 x i1> @fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @fneg_fneg_swap_pred_vec_undef( ; CHECK-LABEL: @fneg_fneg_swap_pred_vec_undef(
; CHECK-NEXT: [[NEG1:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[NEG2:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[Y:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[NEG1]], [[NEG2]]
; CHECK-NEXT: ret <2 x i1> [[CMP]] ; CHECK-NEXT: ret <2 x i1> [[CMP]]
; ;
%neg1 = fsub <2 x float> <float -0.0, float undef>, %x %neg1 = fsub <2 x float> <float -0.0, float undef>, %x

View File

@ -224,9 +224,7 @@ define <2 x float> @fneg_fneg_vec(<2 x float> %x, <2 x float> %y) {
define <2 x float> @fneg_fneg_vec_undef_elts(<2 x float> %x, <2 x float> %y) { define <2 x float> @fneg_fneg_vec_undef_elts(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @fneg_fneg_vec_undef_elts( ; CHECK-LABEL: @fneg_fneg_vec_undef_elts(
; CHECK-NEXT: [[XNEG:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[YNEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[Y:%.*]]
; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[XNEG]], [[YNEG]]
; CHECK-NEXT: ret <2 x float> [[DIV]] ; CHECK-NEXT: ret <2 x float> [[DIV]]
; ;
%xneg = fsub <2 x float> <float undef, float -0.0>, %x %xneg = fsub <2 x float> <float undef, float -0.0>, %x
@ -267,8 +265,7 @@ define <2 x float> @fneg_dividend_constant_divisor_vec(<2 x float> %x) {
define <2 x float> @fneg_dividend_constant_divisor_vec_undef_elt(<2 x float> %x) { define <2 x float> @fneg_dividend_constant_divisor_vec_undef_elt(<2 x float> %x) {
; CHECK-LABEL: @fneg_dividend_constant_divisor_vec_undef_elt( ; CHECK-LABEL: @fneg_dividend_constant_divisor_vec_undef_elt(
; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>
; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf <2 x float> [[NEG]], <float 3.000000e+00, float -8.000000e+00>
; CHECK-NEXT: ret <2 x float> [[DIV]] ; CHECK-NEXT: ret <2 x float> [[DIV]]
; ;
%neg = fsub <2 x float> <float undef, float -0.0>, %x %neg = fsub <2 x float> <float undef, float -0.0>, %x

View File

@ -32,9 +32,7 @@ define <2 x float> @fma_fneg_x_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x f
define <2 x float> @fma_fneg_x_fneg_y_vec_undef(<2 x float> %x, <2 x float> %y, <2 x float> %z) { define <2 x float> @fma_fneg_x_fneg_y_vec_undef(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_undef( ; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_undef(
; CHECK-NEXT: [[XN:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]] ; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
; CHECK-NEXT: [[YN:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[Y:%.*]]
; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[XN]], <2 x float> [[YN]], <2 x float> [[Z:%.*]])
; CHECK-NEXT: ret <2 x float> [[FMA]] ; CHECK-NEXT: ret <2 x float> [[FMA]]
; ;
%xn = fsub <2 x float> <float -0.0, float undef>, %x %xn = fsub <2 x float> <float -0.0, float undef>, %x

View File

@ -24,8 +24,7 @@ define <2 x float> @neg_constant_vec(<2 x float> %x) {
define <2 x float> @neg_constant_vec_undef(<2 x float> %x) { define <2 x float> @neg_constant_vec_undef(<2 x float> %x) {
; CHECK-LABEL: @neg_constant_vec_undef( ; CHECK-LABEL: @neg_constant_vec_undef(
; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[X:%.*]], <float -2.000000e+00, float -3.000000e+00>
; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[SUB]], <float 2.000000e+00, float 3.000000e+00>
; CHECK-NEXT: ret <2 x float> [[MUL]] ; CHECK-NEXT: ret <2 x float> [[MUL]]
; ;
%sub = fsub <2 x float> <float undef, float -0.0>, %x %sub = fsub <2 x float> <float undef, float -0.0>, %x
@ -69,9 +68,7 @@ define <2 x float> @neg_neg_vec(<2 x float> %x, <2 x float> %y) {
define <2 x float> @neg_neg_vec_undef(<2 x float> %x, <2 x float> %y) { define <2 x float> @neg_neg_vec_undef(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @neg_neg_vec_undef( ; CHECK-LABEL: @neg_neg_vec_undef(
; CHECK-NEXT: [[SUB1:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SUB2:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[Y:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[SUB1]], [[SUB2]]
; CHECK-NEXT: ret <2 x float> [[MUL]] ; CHECK-NEXT: ret <2 x float> [[MUL]]
; ;
%sub1 = fsub <2 x float> <float -0.0, float undef>, %x %sub1 = fsub <2 x float> <float -0.0, float undef>, %x
@ -136,8 +133,8 @@ define <2 x float> @neg_sink_vec(<2 x float> %x, <2 x float> %y) {
define <2 x float> @neg_sink_vec_undef(<2 x float> %x, <2 x float> %y) { define <2 x float> @neg_sink_vec_undef(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @neg_sink_vec_undef( ; CHECK-LABEL: @neg_sink_vec_undef(
; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[Y:%.*]] ; CHECK-NEXT: [[MUL:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
; CHECK-NEXT: ret <2 x float> [[MUL]] ; CHECK-NEXT: ret <2 x float> [[MUL]]
; ;
%sub = fsub <2 x float> <float undef, float -0.0>, %x %sub = fsub <2 x float> <float undef, float -0.0>, %x