OSDN Git Service

[PatternMatch, InstSimplify] allow undef elements when matching any vector FP zero
authorSanjay Patel <spatel@rotateright.com>
Thu, 15 Mar 2018 14:29:27 +0000 (14:29 +0000)
committerSanjay Patel <spatel@rotateright.com>
Thu, 15 Mar 2018 14:29:27 +0000 (14:29 +0000)
This matcher implementation appears to be slightly more efficient than
the generic constant check that it is replacing because every use was
for matching FP patterns, but the previous code would check int and
pointer type nulls too.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327627 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/PatternMatch.h
lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstSimplify/fast-math.ll

index 20bdcdd..fec89dc 100644 (file)
@@ -144,19 +144,6 @@ struct match_zero {
 /// zero_initializer for vectors and ConstantPointerNull for pointers.
 inline match_zero m_Zero() { return match_zero(); }
 
-struct match_any_zero {
-  template <typename ITy> bool match(ITy *V) {
-    if (const auto *C = dyn_cast<Constant>(V))
-      return C->isZeroValue();
-    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 and positive zero
-inline match_any_zero m_AnyZero() { return match_any_zero(); }
-
 struct apint_match {
   const APInt *&Res;
 
@@ -419,6 +406,15 @@ inline cstfp_pred_ty<is_nan> m_NaN() {
   return cstfp_pred_ty<is_nan>();
 }
 
+struct is_any_zero_fp {
+  bool isValue(const APFloat &C) { return C.isZero(); }
+};
+
+/// Match a floating-point negative zero or positive zero
+inline cstfp_pred_ty<is_any_zero_fp> m_AnyZeroFP() {
+  return cstfp_pred_ty<is_any_zero_fp>();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 template <typename Class> struct bind_ty {
index 773c3ec..5e43cb7 100644 (file)
@@ -4175,8 +4175,8 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
   // X = -0.0: ( 0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0
   // X =  0.0: (-0.0 - ( 0.0)) + ( 0.0) == (-0.0) + ( 0.0) == 0.0
   // X =  0.0: ( 0.0 - ( 0.0)) + ( 0.0) == ( 0.0) + ( 0.0) == 0.0
-  if (FMF.noNaNs() && (match(Op0, m_FSub(m_AnyZero(), m_Specific(Op1))) ||
-                       match(Op1, m_FSub(m_AnyZero(), m_Specific(Op0)))))
+  if (FMF.noNaNs() && (match(Op0, m_FSub(m_AnyZeroFP(), m_Specific(Op1))) ||
+                       match(Op1, m_FSub(m_AnyZeroFP(), m_Specific(Op0)))))
     return ConstantFP::getNullValue(Op0->getType());
 
   return nullptr;
@@ -4207,8 +4207,8 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
     return X;
 
   // fsub 0.0, (fsub 0.0, X) ==> X if signed zeros are ignored.
-  if (FMF.noSignedZeros() && match(Op0, m_AnyZero()) &&
-      match(Op1, m_FSub(m_AnyZero(), m_Value(X))))
+  if (FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()) &&
+      match(Op1, m_FSub(m_AnyZeroFP(), m_Value(X))))
     return X;
 
   // fsub nnan x, x ==> 0.0
@@ -4232,8 +4232,8 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
     return Op0;
 
   // fmul nnan nsz X, 0 ==> 0
-  if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZero()))
-    return Op1;
+  if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZeroFP()))
+    return ConstantFP::getNullValue(Op0->getType());
 
   // sqrt(X) * sqrt(X) --> X
   Value *X;
@@ -4275,8 +4275,8 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
   // 0 / X -> 0
   // Requires that NaNs are off (X could be zero) and signed zeroes are
   // ignored (X could be positive or negative, so the output sign is unknown).
-  if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZero()))
-    return Op0;
+  if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()))
+    return ConstantFP::getNullValue(Op0->getType());
 
   if (FMF.noNaNs()) {
     // X / X -> 1.0 is legal when NaNs are ignored.
index bed39fb..493d7e1 100644 (file)
@@ -20,8 +20,7 @@ define float @mul_zero_2(float %a) {
 
 define <2 x float> @mul_zero_nsz_nnan_vec_undef(<2 x float> %a) {
 ; CHECK-LABEL: @mul_zero_nsz_nnan_vec_undef(
-; CHECK-NEXT:    [[B:%.*]] = fmul nnan nsz <2 x float> [[A:%.*]], <float 0.000000e+00, float undef>
-; CHECK-NEXT:    ret <2 x float> [[B]]
+; CHECK-NEXT:    ret <2 x float> zeroinitializer
 ;
   %b = fmul nsz nnan <2 x float> %a, <float 0.0, float undef>
   ret <2 x float> %b
@@ -79,9 +78,7 @@ define <2 x float> @fadd_fnegx_commute_vec(<2 x float> %x) {
 
 define <2 x float> @fadd_fnegx_commute_vec_undef(<2 x float> %x) {
 ; CHECK-LABEL: @fadd_fnegx_commute_vec_undef(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = fadd nnan <2 x float> [[X]], [[NEGX]]
-; CHECK-NEXT:    ret <2 x float> [[R]]
+; CHECK-NEXT:    ret <2 x float> zeroinitializer
 ;
   %negx = fsub <2 x float> <float undef, float -0.0>, %x
   %r = fadd nnan <2 x float> %x, %negx
@@ -181,9 +178,7 @@ define float @fsub_0_0_x(float %a) {
 
 define <2 x float> @fsub_0_0_x_vec_undef1(<2 x float> %a) {
 ; CHECK-LABEL: @fsub_0_0_x_vec_undef1(
-; CHECK-NEXT:    [[T1:%.*]] = fsub <2 x float> <float 0.000000e+00, float undef>, [[A:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = fsub nsz <2 x float> zeroinitializer, [[T1]]
-; CHECK-NEXT:    ret <2 x float> [[RET]]
+; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
 ;
   %t1 = fsub <2 x float> <float 0.0, float undef>, %a
   %ret = fsub nsz <2 x float> zeroinitializer, %t1
@@ -192,9 +187,7 @@ define <2 x float> @fsub_0_0_x_vec_undef1(<2 x float> %a) {
 
 define <2 x float> @fsub_0_0_x_vec_undef2(<2 x float> %a) {
 ; CHECK-LABEL: @fsub_0_0_x_vec_undef2(
-; CHECK-NEXT:    [[T1:%.*]] = fsub <2 x float> zeroinitializer, [[A:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = fsub nsz <2 x float> <float undef, float -0.000000e+00>, [[T1]]
-; CHECK-NEXT:    ret <2 x float> [[RET]]
+; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
 ;
   %t1 = fsub <2 x float> zeroinitializer, %a
   %ret = fsub nsz <2 x float> <float undef, float -0.0>, %t1
@@ -229,8 +222,7 @@ define double @fdiv_zero_by_x(double %x) {
 
 define <2 x double> @fdiv_zero_by_x_vec_undef(<2 x double> %x) {
 ; CHECK-LABEL: @fdiv_zero_by_x_vec_undef(
-; CHECK-NEXT:    [[R:%.*]] = fdiv nnan nsz <2 x double> <double 0.000000e+00, double undef>, [[X:%.*]]
-; CHECK-NEXT:    ret <2 x double> [[R]]
+; CHECK-NEXT:    ret <2 x double> zeroinitializer
 ;
   %r = fdiv nnan nsz <2 x double> <double 0.0, double undef>, %x
   ret <2 x double> %r