[llvm] r327307 - [PatternMatch, InstSimplify] allow undef elements when matching vector -0.0

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 12 11:17:01 PDT 2018


Author: spatel
Date: Mon Mar 12 11:17:01 2018
New Revision: 327307

URL: http://llvm.org/viewvc/llvm-project?rev=327307&view=rev
Log:
[PatternMatch, InstSimplify] allow undef elements when matching vector -0.0

This is the FP equivalent of D42818. Use it for the few cases in InstSimplify 
with -0.0 folds (that's the only current use of m_NegZero()).

Differential Revision: https://reviews.llvm.org/D43792

Modified:
    llvm/trunk/include/llvm/IR/PatternMatch.h
    llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll

Modified: llvm/trunk/include/llvm/IR/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PatternMatch.h?rev=327307&r1=327306&r2=327307&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/IR/PatternMatch.h Mon Mar 12 11:17:01 2018
@@ -144,20 +144,6 @@ struct match_zero {
 /// zero_initializer for vectors and ConstantPointerNull for pointers.
 inline match_zero m_Zero() { return match_zero(); }
 
-struct match_neg_zero {
-  template <typename ITy> bool match(ITy *V) {
-    if (const auto *C = dyn_cast<Constant>(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 <typename ITy> bool match(ITy *V) {
     if (const auto *C = dyn_cast<Constant>(V))
@@ -250,8 +236,9 @@ template <int64_t Val> inline constantin
   return constantint_match<Val>();
 }
 
-/// 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 <typename Predicate> struct cst_pred_ty : public Predicate {
   template <typename ITy> bool match(ITy *V) {
     if (const auto *CI = dyn_cast<ConstantInt>(V))
@@ -306,6 +293,38 @@ template <typename Predicate> struct api
   }
 };
 
+/// 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 <typename Predicate> struct cstfp_pred_ty : public Predicate {
+  template <typename ITy> bool match(ITy *V) {
+    if (const auto *CF = dyn_cast<ConstantFP>(V))
+      return this->isValue(CF->getValueAPF());
+    if (V->getType()->isVectorTy()) {
+      if (const auto *C = dyn_cast<Constant>(V)) {
+        if (const auto *CF = dyn_cast_or_null<ConstantFP>(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<UndefValue>(Elt))
+            continue;
+          auto *CF = dyn_cast<ConstantFP>(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 @@ inline cst_pred_ty<is_sign_mask> m_SignM
   return cst_pred_ty<is_sign_mask>();
 }
 
+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<is_neg_zero> m_NegZero() {
+  return cstfp_pred_ty<is_neg_zero>();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 template <typename Class> struct bind_ty {

Modified: llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll?rev=327307&r1=327306&r2=327307&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/floating-point-arithmetic.ll Mon Mar 12 11:17:01 2018
@@ -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:%.*]], <float undef, float -0.000000e+00>
-; CHECK-NEXT:    ret <2 x float> [[R]]
+; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
 ;
   %r = fsub nsz <2 x float> %x, <float undef, float -0.0>
   ret <2 x float> %r
@@ -31,9 +30,7 @@ define <2 x float> @fsub_-0_-0_x_vec(<2
 
 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> <float undef, float -0.000000e+00>, [[A:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[T1]]
-; CHECK-NEXT:    ret <2 x float> [[RET]]
+; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
 ;
   %t1 = fsub <2 x float> <float undef, float -0.0>, %a
   %ret = fsub <2 x float> <float -0.0, float undef>, %t1
@@ -84,8 +81,7 @@ define float @fadd_x_n0(float %a) {
 
 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:%.*]], <float -0.000000e+00, float undef>
-; CHECK-NEXT:    ret <2 x float> [[RET]]
+; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
 ;
   %ret = fadd <2 x float> %a, <float -0.0, float undef>
   ret <2 x float> %ret




More information about the llvm-commits mailing list