[llvm] 89f0314 - Revert "InstSimplify: Use correct interested FP classes when simplifying fcmp"

Zequan Wu via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 11:54:34 PDT 2023


Author: Zequan Wu
Date: 2023-09-01T14:54:27-04:00
New Revision: 89f0314ee14a4d7f5a92fd63574ba545863df016

URL: https://github.com/llvm/llvm-project/commit/89f0314ee14a4d7f5a92fd63574ba545863df016
DIFF: https://github.com/llvm/llvm-project/commit/89f0314ee14a4d7f5a92fd63574ba545863df016.diff

LOG: Revert "InstSimplify: Use correct interested FP classes when simplifying fcmp"
Revert "InstSimplify: Add baseline tests for reported regression"
Revert "InstSimplify: Start cleaning up simplifyFCmpInst"

This reverts commit 0637b00041c7d6a191d51d9966c4f5f41fb97ab5.
This reverts commit 239fb206de35935416e652b89725d5f3193f78f5.
This reverts commit ddb3f12c428bc4bd5a98913d74dfd7f2402bdfd8.

These commits causes crashes when compiling chromium code, attached reduced ir at: https://reviews.llvm.org/D151887#4634914

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/ValueTracking.h
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/Attributor/nofpclass.ll
    llvm/test/Transforms/InstCombine/fcmp.ll
    llvm/test/Transforms/InstCombine/is_fpclass.ll
    llvm/test/Transforms/InstSimplify/floating-point-compare.ll
    llvm/test/Transforms/InstSimplify/known-never-infinity.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 695f2fecae885b..3521fa8be3b691 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -18,7 +18,6 @@
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
-#include "llvm/IR/FMF.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Intrinsics.h"
 #include <cassert>
@@ -230,10 +229,6 @@ std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
                                                 const Function &F, Value *LHS,
                                                 Value *RHS,
                                                 bool LookThroughSrc = true);
-std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
-                                                const Function &F, Value *LHS,
-                                                const APFloat *ConstRHS,
-                                                bool LookThroughSrc = true);
 
 struct KnownFPClass {
   /// Floating-point classes the value could be one of.
@@ -476,28 +471,6 @@ KnownFPClass computeKnownFPClass(
     const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr,
     bool UseInstrInfo = true);
 
-/// Wrapper to account for known fast math flags at the use instruction.
-inline KnownFPClass computeKnownFPClass(
-    const Value *V, FastMathFlags FMF, const DataLayout &DL,
-    FPClassTest InterestedClasses = fcAllFlags, unsigned Depth = 0,
-    const TargetLibraryInfo *TLI = nullptr, AssumptionCache *AC = nullptr,
-    const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr,
-    bool UseInstrInfo = true) {
-  if (FMF.noNaNs())
-    InterestedClasses &= ~fcNan;
-  if (FMF.noInfs())
-    InterestedClasses &= ~fcInf;
-
-  KnownFPClass Result = computeKnownFPClass(V, DL, InterestedClasses, Depth,
-                                            TLI, AC, CxtI, DT, UseInstrInfo);
-
-  if (FMF.noNaNs())
-    Result.KnownFPClasses &= ~fcNan;
-  if (FMF.noInfs())
-    Result.KnownFPClasses &= ~fcInf;
-  return Result;
-}
-
 /// Return true if we can prove that the specified FP value is never equal to
 /// -0.0. Users should use caution when considering PreserveSign
 /// denormal-fp-math.

diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 040c2e55d87ced..600418a5b7debf 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4060,6 +4060,19 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
   if (Pred == FCmpInst::FCMP_TRUE)
     return getTrue(RetTy);
 
+  // Fold (un)ordered comparison if we can determine there are no NaNs.
+  if (Pred == FCmpInst::FCMP_UNO || Pred == FCmpInst::FCMP_ORD)
+    if (FMF.noNaNs() ||
+        (isKnownNeverNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT) &&
+         isKnownNeverNaN(RHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)))
+      return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);
+
+  // NaN is unordered; NaN is not ordered.
+  assert((FCmpInst::isOrdered(Pred) || FCmpInst::isUnordered(Pred)) &&
+         "Comparison must be either ordered or unordered");
+  if (match(RHS, m_NaN()))
+    return ConstantInt::get(RetTy, CmpInst::isUnordered(Pred));
+
   // fcmp pred x, poison and  fcmp pred poison, x
   // fold to poison
   if (isa<PoisonValue>(LHS) || isa<PoisonValue>(RHS))
@@ -4081,86 +4094,80 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
       return getFalse(RetTy);
   }
 
-  // Fold (un)ordered comparison if we can determine there are no NaNs.
-  //
-  // This catches the 2 variable input case, constants are handled below as a
-  // class-like compare.
-  if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {
-    if (FMF.noNaNs() ||
-        (isKnownNeverNaN(RHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT) &&
-         isKnownNeverNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)))
-      return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);
-  }
-
-  const APFloat *C = nullptr;
-  match(RHS, m_APFloatAllowUndef(C));
-  std::optional<KnownFPClass> FullKnownClassLHS;
-
-  // Lazily compute the possible classes for LHS. Avoid computing it twice if
-  // RHS is a 0.
-  auto computeLHSClass = [=, &FullKnownClassLHS](FPClassTest InterestedFlags =
-                                                     fcAllFlags) {
-    if (FullKnownClassLHS)
-      return *FullKnownClassLHS;
-    return computeKnownFPClass(LHS, FMF, Q.DL, InterestedFlags, 0, Q.TLI, Q.AC,
-                               Q.CxtI, Q.DT, Q.IIQ.UseInstrInfo);
-  };
+  // 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.
+    if (C->isInfinity()) {
+      if (C->isNegative()) {
+        switch (Pred) {
+        case FCmpInst::FCMP_OLT:
+          // No value is ordered and less than negative infinity.
+          return getFalse(RetTy);
+        case FCmpInst::FCMP_UGE:
+          // All values are unordered with or at least negative infinity.
+          return getTrue(RetTy);
+        default:
+          break;
+        }
+      } else {
+        switch (Pred) {
+        case FCmpInst::FCMP_OGT:
+          // No value is ordered and greater than infinity.
+          return getFalse(RetTy);
+        case FCmpInst::FCMP_ULE:
+          // All values are unordered with and at most infinity.
+          return getTrue(RetTy);
+        default:
+          break;
+        }
+      }
 
-  if (C && Q.CxtI) {
-    // Fold out compares that express a class test.
-    //
-    // FIXME: Should be able to perform folds without context
-    // instruction. Always pass in the context function?
-
-    const Function *ParentF = Q.CxtI->getFunction();
-    auto [ClassVal, ClassTest] = fcmpToClassTest(Pred, *ParentF, LHS, C);
-    if (ClassVal) {
-      FullKnownClassLHS = computeLHSClass();
-      if ((FullKnownClassLHS->KnownFPClasses & ClassTest) == fcNone)
+      // LHS == Inf
+      if (Pred == FCmpInst::FCMP_OEQ &&
+          isKnownNeverInfinity(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
+        return getFalse(RetTy);
+      // LHS != Inf
+      if (Pred == FCmpInst::FCMP_UNE &&
+          isKnownNeverInfinity(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
+        return getTrue(RetTy);
+      // LHS == Inf || LHS == NaN
+      if (Pred == FCmpInst::FCMP_UEQ &&
+          isKnownNeverInfOrNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
         return getFalse(RetTy);
-      if ((FullKnownClassLHS->KnownFPClasses & ~ClassTest) == fcNone)
+      // LHS != Inf && LHS != NaN
+      if (Pred == FCmpInst::FCMP_ONE &&
+          isKnownNeverInfOrNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
         return getTrue(RetTy);
     }
-  }
-
-  // Handle fcmp with constant RHS.
-  if (C) {
-    // TODO: Need version fcmpToClassTest which returns implied class when the
-    // compare isn't a complete class test. e.g. > 1.0 implies fcPositive, but
-    // isn't implementable as a class call.
     if (C->isNegative() && !C->isNegZero()) {
-      FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
-
-      // FIXME: This assert won't always hold if we depend on the context
-      // instruction above
       assert(!C->isNaN() && "Unexpected NaN constant!");
       // TODO: We can catch more cases by using a range check rather than
       //       relying on CannotBeOrderedLessThanZero.
       switch (Pred) {
       case FCmpInst::FCMP_UGE:
       case FCmpInst::FCMP_UGT:
-      case FCmpInst::FCMP_UNE: {
-        KnownFPClass KnownClass = computeLHSClass(Interested);
-
+      case FCmpInst::FCMP_UNE:
         // (X >= 0) implies (X > C) when (C < 0)
-        if (KnownClass.cannotBeOrderedLessThanZero())
+        if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0,
+                                        Q.AC, Q.CxtI, Q.DT))
           return getTrue(RetTy);
         break;
-      }
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OLE:
-      case FCmpInst::FCMP_OLT: {
-        KnownFPClass KnownClass = computeLHSClass(Interested);
-
+      case FCmpInst::FCMP_OLT:
         // (X >= 0) implies !(X < C) when (C < 0)
-        if (KnownClass.cannotBeOrderedLessThanZero())
+        if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI,
+                                        Q.DT))
           return getFalse(RetTy);
         break;
-      }
       default:
         break;
       }
     }
+
     // Check comparison of [minnum/maxnum with constant] with other constant.
     const APFloat *C2;
     if ((match(LHS, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_APFloat(C2))) &&
@@ -4207,17 +4214,13 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
     }
   }
 
-  // TODO: Could fold this with above if there were a matcher which returned all
-  // classes in a non-splat vector.
   if (match(RHS, m_AnyZeroFP())) {
     switch (Pred) {
     case FCmpInst::FCMP_OGE:
     case FCmpInst::FCMP_ULT: {
-      FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
-      if (!FMF.noNaNs())
-        Interested |= fcNan;
-
-      KnownFPClass Known = computeLHSClass(Interested);
+      FPClassTest Interested = FMF.noNaNs() ? fcNegative : fcNegative | fcNan;
+      KnownFPClass Known = computeKnownFPClass(LHS, Q.DL, Interested, 0,
+                                               Q.TLI, Q.AC, Q.CxtI, Q.DT);
 
       // Positive or zero X >= 0.0 --> true
       // Positive or zero X <  0.0 --> false
@@ -4227,16 +4230,12 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
       break;
     }
     case FCmpInst::FCMP_UGE:
-    case FCmpInst::FCMP_OLT: {
-      FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
-      KnownFPClass Known = computeLHSClass(Interested);
-
+    case FCmpInst::FCMP_OLT:
       // Positive or zero or nan X >= 0.0 --> true
       // Positive or zero or nan X <  0.0 --> false
-      if (Known.cannotBeOrderedLessThanZero())
+      if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
         return Pred == FCmpInst::FCMP_UGE ? getTrue(RetTy) : getFalse(RetTy);
       break;
-    }
     default:
       break;
     }
@@ -6817,9 +6816,6 @@ static Value *simplifyInstructionWithOperands(Instruction *I,
                                               const SimplifyQuery &SQ,
                                               unsigned MaxRecurse) {
   assert(I->getFunction() && "instruction should be inserted in a function");
-  assert((!SQ.CxtI || SQ.CxtI->getFunction() == I->getFunction()) &&
-         "context instruction should be in the same function");
-
   const SimplifyQuery Q = SQ.CxtI ? SQ : SQ.getWithInstruction(I);
 
   switch (I->getOpcode()) {

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 801814e0c18a83..0c31dc22b871ef 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4007,15 +4007,9 @@ std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred,
                                                       Value *LHS, Value *RHS,
                                                       bool LookThroughSrc) {
   const APFloat *ConstRHS;
-  if (!match(RHS, m_APFloatAllowUndef(ConstRHS)))
+  if (!match(RHS, m_APFloat(ConstRHS)))
     return {nullptr, fcNone};
 
-  return fcmpToClassTest(Pred, F, LHS, ConstRHS, LookThroughSrc);
-}
-
-std::pair<Value *, FPClassTest>
-llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
-                      const APFloat *ConstRHS, bool LookThroughSrc) {
   // fcmp ord x, zero|normal|subnormal|inf -> ~fcNan
   if (Pred == FCmpInst::FCMP_ORD && !ConstRHS->isNaN())
     return {LHS, ~fcNan};

diff  --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index 051ae8b8fe3d5a..2690bba123a345 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -600,7 +600,8 @@ define half @assume_fcmp_fabs_with_other_fabs_assume_fallback(half %arg) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR16]]
 ; CHECK-NEXT:    [[UNRELATED_FABS:%.*]] = fcmp oeq half [[FABS]], 0xH0000
 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR16]]
-; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR16]]
+; CHECK-NEXT:    [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR16]]
 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf norm) [[ARG]])
 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf nzero sub norm) [[FABS]])
 ; CHECK-NEXT:    ret half [[ARG]]

diff  --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 159c84d0dd8aa9..5c4380b14397dc 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -718,7 +718,9 @@ define i1 @is_signbit_clear_nonzero(double %x) {
 
 define i1 @is_signbit_set_simplify_zero(double %x) {
 ; CHECK-LABEL: @is_signbit_set_simplify_zero(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 0.000000e+00, double [[X:%.*]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %s = call double @llvm.copysign.f64(double 0.0, double %x)
   %r = fcmp ogt double %s, 0.0
@@ -729,7 +731,9 @@ define i1 @is_signbit_set_simplify_zero(double %x) {
 
 define i1 @is_signbit_set_simplify_nan(double %x) {
 ; CHECK-LABEL: @is_signbit_set_simplify_nan(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 0xFFFFFFFFFFFFFFFF, double [[X:%.*]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)
   %r = fcmp ogt double %s, 0.0

diff  --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll
index ad0bcd1b0c437c..2f399e7e23a637 100644
--- a/llvm/test/Transforms/InstCombine/is_fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/is_fpclass.ll
@@ -2444,7 +2444,8 @@ define <2 x i1> @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan_
 
 define i1 @test_class_is_zero_nozero_src(float nofpclass(zero) %arg) {
 ; CHECK-LABEL: @test_class_is_zero_nozero_src(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %class = call i1 @llvm.is.fpclass.f32(float %arg, i32 96)
   ret i1 %class
@@ -2577,7 +2578,8 @@ define i1 @test_class_is_neginf_or_nopinf_src(float nofpclass(pinf) %arg) {
 
 define i1 @test_class_is_neginf_noninf_src(float nofpclass(ninf) %arg) {
 ; CHECK-LABEL: @test_class_is_neginf_noninf_src(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %class = call i1 @llvm.is.fpclass.f32(float %arg, i32 4)
   ret i1 %class
@@ -2602,7 +2604,8 @@ define i1 @test_class_is_posinf_noninf_src(float nofpclass(ninf) %arg) {
 
 define i1 @test_class_is_posinf_nopinf_src(float nofpclass(pinf) %arg) {
 ; CHECK-LABEL: @test_class_is_posinf_nopinf_src(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %class = call i1 @llvm.is.fpclass.f32(float %arg, i32 512)
   ret i1 %class
@@ -2730,7 +2733,8 @@ define i1 @test_class_is_nan_assume_uno(float %x) {
 ; CHECK-LABEL: @test_class_is_nan_assume_uno(
 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CLASS:%.*]] = fcmp uno float [[X]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %ord = fcmp uno float %x, 0.0
   call void @llvm.assume(i1 %ord)

diff  --git a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
index 62dd37d9b74e62..a88057e4d4d93e 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
@@ -656,7 +656,8 @@ define i1 @assume_nan_ord(float %x) {
 ; CHECK-LABEL: @assume_nan_ord(
 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO]])
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[X]], 1.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %uno = fcmp uno float %x, 0.0
   call void @llvm.assume(i1 %uno)
@@ -680,7 +681,8 @@ define i1 @assume_nan_uno(float %x) {
 ; CHECK-LABEL: @assume_nan_uno(
 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO]])
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[X]], 1.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %uno = fcmp uno float %x, 0.0
   call void @llvm.assume(i1 %uno)
@@ -1523,7 +1525,10 @@ define i1 @fcmp_olt_0_assumed_oge_zero(float %x) {
 define i1 @ogt_zero_fabs_select_negone_or_pinf(i1 %cond) {
 ; CHECK-LABEL: @ogt_zero_fabs_select_negone_or_pinf(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND:%.*]], float -1.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT:    [[ONE:%.*]] = fcmp ogt float [[FABS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[ONE]]
 ;
 entry:
   %select = select i1 %cond, float -1.0, float 0x7FF0000000000000
@@ -1535,7 +1540,10 @@ entry:
 define i1 @ogt_zero_fabs_select_one_or_ninf(i1 %cond) {
 ; CHECK-LABEL: @ogt_zero_fabs_select_one_or_ninf(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND:%.*]], float 1.000000e+00, float 0xFFF0000000000000
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT:    [[ONE:%.*]] = fcmp ogt float [[FABS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[ONE]]
 ;
 entry:
   %select = select i1 %cond, float 1.0, float 0xFFF0000000000000
@@ -1544,114 +1552,6 @@ entry:
   ret i1 %one
 }
 
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_ieee(float %arg, float %arg1) {
-; CHECK-LABEL: @fast_square_must_be_positive_ieee(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT:    ret float [[I3]]
-;
-bb:
-  %i = fmul float %arg, %arg
-  %i2 = fmul float %arg1, %arg1
-  %i3 = fadd float %i2, %i
-  %i4 = fcmp olt float %i3, 0.000000e+00
-  %i5 = select i1 %i4, float 0.000000e+00, float %i3
-  ret float %i5
-}
-
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_ieee_nnan(float %arg, float %arg1) {
-; CHECK-LABEL: @fast_square_must_be_positive_ieee_nnan(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT:    ret float [[I3]]
-;
-bb:
-  %i = fmul float %arg, %arg
-  %i2 = fmul float %arg1, %arg1
-  %i3 = fadd float %i2, %i
-  %i4 = fcmp nnan olt float %i3, 0.000000e+00
-  %i5 = select i1 %i4, float 0.000000e+00, float %i3
-  ret float %i5
-}
-
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_daz(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @fast_square_must_be_positive_daz(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT:    ret float [[I3]]
-;
-bb:
-  %i = fmul float %arg, %arg
-  %i2 = fmul float %arg1, %arg1
-  %i3 = fadd float %i2, %i
-  %i4 = fcmp olt float %i3, 0.000000e+00
-  %i5 = select i1 %i4, float 0.000000e+00, float %i3
-  ret float %i5
-}
-
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_daz_nnan(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @fast_square_must_be_positive_daz_nnan(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT:    ret float [[I3]]
-;
-bb:
-  %i = fmul float %arg, %arg
-  %i2 = fmul float %arg1, %arg1
-  %i3 = fadd float %i2, %i
-  %i4 = fcmp nnan olt float %i3, 0.000000e+00
-  %i5 = select i1 %i4, float 0.000000e+00, float %i3
-  ret float %i5
-}
-
-; Make the compare to negative constant is folded out
-define float @must_be_olt_negative_constant_daz(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @must_be_olt_negative_constant_daz(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT:    ret float [[I3]]
-;
-bb:
-  %i = fmul float %arg, %arg
-  %i2 = fmul float %arg1, %arg1
-  %i3 = fadd float %i2, %i
-  %i4 = fcmp olt float %i3, -1.0
-  %i5 = select i1 %i4, float 0.000000e+00, float %i3
-  ret float %i5
-}
-
-; Make the compare to negative constant is folded out
-define float @must_be_olt_negative_constant_daz_nnan(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @must_be_olt_negative_constant_daz_nnan(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT:    ret float [[I3]]
-;
-bb:
-  %i = fmul float %arg, %arg
-  %i2 = fmul float %arg1, %arg1
-  %i3 = fadd float %i2, %i
-  %i4 = fcmp nnan olt float %i3, -1.0
-  %i5 = select i1 %i4, float 0.000000e+00, float %i3
-  ret float %i5
-}
-
 declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
 declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)
@@ -1671,5 +1571,3 @@ declare double @llvm.sqrt.f64(double)
 declare double @llvm.copysign.f64(double, double)
 declare half @llvm.fabs.f16(half)
 declare void @llvm.assume(i1 noundef)
-
-attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }

diff  --git a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
index efa19aa0999a7a..a7b7e0b4b1fa6c 100644
--- a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
+++ b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
@@ -753,7 +753,11 @@ define i1 @isKnownNeverInfinity_cos(double %x) {
 define i1 @isKnownNeverInfinity_log(double %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_log
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00)
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X_CLAMP_ZERO]], 1.000000e+00
+; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log.f64(double [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
   %a = fadd ninf double %x.clamp.zero, 1.0
@@ -765,7 +769,10 @@ define i1 @isKnownNeverInfinity_log(double %x) {
 define i1 @isNotKnownNeverInfinity_log_maybe_negative(double %x) {
 ; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log_maybe_negative
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[X_NOT_INF:%.*]] = fadd ninf double [[X]], 1.000000e+00
+; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log.f64(double [[X_NOT_INF]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[R]]
 ;
 
   %x.not.inf = fadd ninf double %x, 1.0
@@ -805,7 +812,11 @@ define i1 @isKnownNeverNegInfinity_log_maybe_0(double %x) {
 define i1 @isKnownNeverInfinity_log10(double %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_log10
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00)
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X_CLAMP_ZERO]], 1.000000e+00
+; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log10.f64(double [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
   %a = fadd ninf double %x.clamp.zero, 1.0
@@ -817,7 +828,10 @@ define i1 @isKnownNeverInfinity_log10(double %x) {
 define i1 @isNotKnownNeverInfinity_log10_maybe_negative(double %x) {
 ; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log10_maybe_negative
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[X_NOT_INF:%.*]] = fadd ninf double [[X]], 1.000000e+00
+; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log10.f64(double [[X_NOT_INF]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[R]]
 ;
 
   %x.not.inf = fadd ninf double %x, 1.0
@@ -857,7 +871,11 @@ define i1 @isKnownNeverNegInfinity_log10_maybe_0(double %x) {
 define i1 @isKnownNeverInfinity_log2(double %x) {
 ; CHECK-LABEL: define i1 @isKnownNeverInfinity_log2
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00)
+; CHECK-NEXT:    [[A:%.*]] = fadd ninf double [[X_CLAMP_ZERO]], 1.000000e+00
+; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log2.f64(double [[A]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
   %a = fadd ninf double %x.clamp.zero, 1.0
@@ -869,7 +887,10 @@ define i1 @isKnownNeverInfinity_log2(double %x) {
 define i1 @isNotKnownNeverInfinity_log2_maybe_negative(double %x) {
 ; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log2_maybe_negative
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[X_NOT_INF:%.*]] = fadd ninf double [[X]], 1.000000e+00
+; CHECK-NEXT:    [[E:%.*]] = call double @llvm.log2.f64(double [[X_NOT_INF]])
+; CHECK-NEXT:    [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[R]]
 ;
 
   %x.not.inf = fadd ninf double %x, 1.0
@@ -1036,7 +1057,10 @@ define i1 @not_ninf_fabs_select_nzero_or_pinf(i1 %cond) {
 ; CHECK-LABEL: define i1 @not_ninf_fabs_select_nzero_or_pinf
 ; CHECK-SAME: (i1 [[COND:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float -0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT:    [[ONE:%.*]] = fcmp one float [[FABS]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[ONE]]
 ;
 entry:
   %select = select i1 %cond, float -0.000000e+00, float 0x7FF0000000000000


        


More information about the llvm-commits mailing list