OSDN Git Service

[InstSimplify] use any-zero matcher for fcmp folds
authorSanjay Patel <spatel@rotateright.com>
Wed, 20 Feb 2019 14:34:00 +0000 (14:34 +0000)
committerSanjay Patel <spatel@rotateright.com>
Wed, 20 Feb 2019 14:34:00 +0000 (14:34 +0000)
The m_APFloat matcher does not work with anything but strict
splat vector constants, so we could miss these folds and then
trigger an assertion in instcombine:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13201

The previous attempt at this in rL354406 had a logic bug that
actually triggered a regression test failure, but I failed to
notice it the first time.

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

lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstSimplify/floating-point-compare.ll

index 843b3e9..ed857dd 100644 (file)
@@ -3648,6 +3648,8 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
   }
 
   // Handle fcmp with constant RHS.
+  // TODO: Use match with a specific FP value, so these work with vectors with
+  // undef lanes.
   const APFloat *C;
   if (match(RHS, m_APFloat(C))) {
     // Check whether the constant is an infinity.
@@ -3676,28 +3678,7 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
         }
       }
     }
-    if (C->isZero()) {
-      switch (Pred) {
-      case FCmpInst::FCMP_OGE:
-        if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI))
-          return getTrue(RetTy);
-        break;
-      case FCmpInst::FCMP_UGE:
-        if (CannotBeOrderedLessThanZero(LHS, Q.TLI))
-          return getTrue(RetTy);
-        break;
-      case FCmpInst::FCMP_ULT:
-        if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI))
-          return getFalse(RetTy);
-        break;
-      case FCmpInst::FCMP_OLT:
-        if (CannotBeOrderedLessThanZero(LHS, Q.TLI))
-          return getFalse(RetTy);
-        break;
-      default:
-        break;
-      }
-    } else if (C->isNegative()) {
+    if (C->isNegative() && !C->isNegZero()) {
       assert(!C->isNaN() && "Unexpected NaN constant!");
       // TODO: We can catch more cases by using a range check rather than
       //       relying on CannotBeOrderedLessThanZero.
@@ -3721,6 +3702,28 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
       }
     }
   }
+  if (match(RHS, m_AnyZeroFP())) {
+    switch (Pred) {
+    case FCmpInst::FCMP_OGE:
+      if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI))
+        return getTrue(RetTy);
+      break;
+    case FCmpInst::FCMP_UGE:
+      if (CannotBeOrderedLessThanZero(LHS, Q.TLI))
+        return getTrue(RetTy);
+      break;
+    case FCmpInst::FCMP_ULT:
+      if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI))
+        return getFalse(RetTy);
+      break;
+    case FCmpInst::FCMP_OLT:
+      if (CannotBeOrderedLessThanZero(LHS, Q.TLI))
+        return getFalse(RetTy);
+      break;
+    default:
+      break;
+    }
+  }
 
   // If the comparison is with the result of a select instruction, check whether
   // comparing with either branch of the select always yields the same value.
index 77db052..5ce56e0 100644 (file)
@@ -399,9 +399,7 @@ define <2 x i1> @fabs_is_not_negative_poszero(<2 x float> %V) {
 
 define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) {
 ; CHECK-LABEL: @fabs_is_not_negative_anyzero(
-; CHECK-NEXT:    [[ABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[V:%.*]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[ABS]], <float 0.000000e+00, float -0.000000e+00>
-; CHECK-NEXT:    ret <2 x i1> [[CMP]]
+; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 ;
   %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
   %cmp = fcmp olt <2 x float> %abs, <float 0.0, float -0.0>
@@ -410,9 +408,7 @@ define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) {
 
 define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) {
 ; CHECK-LABEL: @fabs_is_not_negative_negzero_undef(
-; CHECK-NEXT:    [[ABS:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[V:%.*]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <3 x float> [[ABS]], <float -0.000000e+00, float -0.000000e+00, float undef>
-; CHECK-NEXT:    ret <3 x i1> [[CMP]]
+; CHECK-NEXT:    ret <3 x i1> zeroinitializer
 ;
   %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
   %cmp = fcmp olt <3 x float> %abs, <float -0.0, float -0.0, float undef>
@@ -421,9 +417,7 @@ define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) {
 
 define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) {
 ; CHECK-LABEL: @fabs_is_not_negative_poszero_undef(
-; CHECK-NEXT:    [[ABS:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[V:%.*]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <3 x float> [[ABS]], <float 0.000000e+00, float 0.000000e+00, float undef>
-; CHECK-NEXT:    ret <3 x i1> [[CMP]]
+; CHECK-NEXT:    ret <3 x i1> zeroinitializer
 ;
   %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
   %cmp = fcmp olt <3 x float> %abs, <float 0.0, float 0.0, float undef>
@@ -432,9 +426,7 @@ define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) {
 
 define <3 x i1> @fabs_is_not_negative_anyzero_undef(<3 x float> %V) {
 ; CHECK-LABEL: @fabs_is_not_negative_anyzero_undef(
-; CHECK-NEXT:    [[ABS:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[V:%.*]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <3 x float> [[ABS]], <float 0.000000e+00, float -0.000000e+00, float undef>
-; CHECK-NEXT:    ret <3 x i1> [[CMP]]
+; CHECK-NEXT:    ret <3 x i1> zeroinitializer
 ;
   %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
   %cmp = fcmp olt <3 x float> %abs, <float 0.0, float -0.0, float undef>