Index: llvm/trunk/include/llvm/IR/PatternMatch.h =================================================================== --- llvm/trunk/include/llvm/IR/PatternMatch.h +++ llvm/trunk/include/llvm/IR/PatternMatch.h @@ -144,20 +144,6 @@ /// zero_initializer for vectors and ConstantPointerNull for pointers. inline match_zero m_Zero() { return match_zero(); } -struct match_neg_zero { - template bool match(ITy *V) { - if (const auto *C = dyn_cast(V)) - return C->isNegativeZeroValue(); - return false; - } -}; - -/// Match an arbitrary zero/null constant. This includes -/// zero_initializer for vectors and ConstantPointerNull for pointers. For -/// floating point constants, this will match negative zero but not positive -/// zero -inline match_neg_zero m_NegZero() { return match_neg_zero(); } - struct match_any_zero { template bool match(ITy *V) { if (const auto *C = dyn_cast(V)) @@ -250,8 +236,9 @@ return constantint_match(); } -/// This helper class is used to match scalar and vector constants that satisfy -/// a specified predicate. For vector constants, undefined elements are ignored. +/// This helper class is used to match scalar and vector integer constants that +/// satisfy a specified predicate. +/// For vector constants, undefined elements are ignored. template struct cst_pred_ty : public Predicate { template bool match(ITy *V) { if (const auto *CI = dyn_cast(V)) @@ -306,6 +293,38 @@ } }; +/// This helper class is used to match scalar and vector floating-point +/// constants that satisfy a specified predicate. +/// For vector constants, undefined elements are ignored. +template struct cstfp_pred_ty : public Predicate { + template bool match(ITy *V) { + if (const auto *CF = dyn_cast(V)) + return this->isValue(CF->getValueAPF()); + if (V->getType()->isVectorTy()) { + if (const auto *C = dyn_cast(V)) { + if (const auto *CF = dyn_cast_or_null(C->getSplatValue())) + return this->isValue(CF->getValueAPF()); + + // Non-splat vector constant: check each element for a match. + unsigned NumElts = V->getType()->getVectorNumElements(); + assert(NumElts != 0 && "Constant vector with no elements?"); + for (unsigned i = 0; i != NumElts; ++i) { + Constant *Elt = C->getAggregateElement(i); + if (!Elt) + return false; + if (isa(Elt)) + continue; + auto *CF = dyn_cast(Elt); + if (!CF || !this->isValue(CF->getValueAPF())) + return false; + } + return true; + } + } + return false; + } +}; + /////////////////////////////////////////////////////////////////////////////// // // Encapsulate constant value queries for use in templated predicate matchers. @@ -395,6 +414,14 @@ return cst_pred_ty(); } +struct is_neg_zero { + bool isValue(const APFloat &C) { return C.isNegZero(); } +}; +/// Match an FP or FP vector with all -0.0 values. +inline cstfp_pred_ty m_NegZero() { + return cstfp_pred_ty(); +} + /////////////////////////////////////////////////////////////////////////////// template struct bind_ty { Index: llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll =================================================================== --- llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll +++ llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll @@ -3,8 +3,7 @@ define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) { ; CHECK-LABEL: @fsub_negzero_vec_undef_elts( -; CHECK-NEXT: [[R:%.*]] = fsub nsz <2 x float> [[X:%.*]], -; CHECK-NEXT: ret <2 x float> [[R]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %r = fsub nsz <2 x float> %x, ret <2 x float> %r @@ -31,9 +30,7 @@ define <2 x float> @fsub_-0_-0_x_vec_undef_elts(<2 x float> %a) { ; CHECK-LABEL: @fsub_-0_-0_x_vec_undef_elts( -; CHECK-NEXT: [[T1:%.*]] = fsub <2 x float> , [[A:%.*]] -; CHECK-NEXT: [[RET:%.*]] = fsub <2 x float> , [[T1]] -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> [[A:%.*]] ; %t1 = fsub <2 x float> , %a %ret = fsub <2 x float> , %t1 @@ -84,8 +81,7 @@ define <2 x float> @fadd_x_n0_vec_undef_elt(<2 x float> %a) { ; CHECK-LABEL: @fadd_x_n0_vec_undef_elt( -; CHECK-NEXT: [[RET:%.*]] = fadd <2 x float> [[A:%.*]], -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> [[A:%.*]] ; %ret = fadd <2 x float> %a, ret <2 x float> %ret