[llvm] effde7f - InstCombine: Match pattern that appears in clang's __builtin_isnormal

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 19 05:12:37 PST 2022


Author: Matt Arsenault
Date: 2022-12-19T08:09:22-05:00
New Revision: effde7f43e26091678dcd5a8f3eb8f344f1be8a7

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

LOG: InstCombine: Match pattern that appears in clang's __builtin_isnormal

and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
and (fcmp ord x, 0), (fcmp u* fabs(x), inf) -> fcmp o* x, inf

Clang emits this peculiar pattern as an isfinite check in
__builtin_isnormal which can be simplified. We should fix clang to
emit this in the first place, but should also fold it here.

Added: 
    

Modified: 
    llvm/include/llvm/IR/InstrTypes.h
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and-fcmp.ll
    llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index cd4d6aefa7d4c..56c59b2d5692f 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -833,6 +833,17 @@ class CmpInst : public Instruction {
     return getInversePredicate(getPredicate());
   }
 
+  /// Returns the ordered variant of a floating point compare.
+  ///
+  /// For example, UEQ -> OEQ, ULT -> OLT, OEQ -> OEQ
+  static Predicate getOrderedPredicate(Predicate Pred) {
+    return static_cast<Predicate>(Pred & FCMP_ORD);
+  }
+
+  Predicate getOrderedPredicate() const {
+    return getOrderedPredicate(getPredicate());
+  }
+
   /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE,
   ///              OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
   /// @returns the inverse predicate for predicate provided in \p pred.

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 3e39dc673d79e..5634008b91fc6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1205,6 +1205,47 @@ Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(ICmpInst *ICmp1,
   return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
 }
 
+/// Ignore all operations which only change the sign of a value, returning the
+/// underlying magnitude value.
+static Value *stripSignOnlyFPOps(Value *Val) {
+  match(Val, m_FNeg(m_Value(Val)));
+  match(Val, m_FAbs(m_Value(Val)));
+  match(Val, m_CopySign(m_Value(Val), m_Value()));
+  return Val;
+}
+
+/// Matches canonical form of isnan, fcmp ord x, 0
+static bool matchIsNotNaN(FCmpInst::Predicate P, Value *LHS, Value *RHS) {
+  return P == FCmpInst::FCMP_ORD && match(RHS, m_AnyZeroFP());
+}
+
+/// Matches fcmp u__ x, +/-inf
+static bool matchUnorderedInfCompare(FCmpInst::Predicate P, Value *LHS,
+                                     Value *RHS) {
+  return FCmpInst::isUnordered(P) && match(RHS, m_Inf());
+}
+
+/// and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
+///
+/// Clang emits this pattern for doing an isfinite check in __builtin_isnormal.
+static Value *matchIsFiniteTest(InstCombiner::BuilderTy &Builder, FCmpInst *LHS,
+                                FCmpInst *RHS) {
+  Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
+  Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
+  FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
+
+  if (!matchIsNotNaN(PredL, LHS0, LHS1) ||
+      !matchUnorderedInfCompare(PredR, RHS0, RHS1))
+    return nullptr;
+
+  IRBuilder<>::FastMathFlagGuard FMFG(Builder);
+  FastMathFlags FMF = LHS->getFastMathFlags();
+  FMF &= RHS->getFastMathFlags();
+  Builder.setFastMathFlags(FMF);
+
+  return Builder.CreateFCmp(FCmpInst::getOrderedPredicate(PredR), RHS0, RHS1);
+}
+
 Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
                                           bool IsAnd, bool IsLogicalSelect) {
   Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
@@ -1263,6 +1304,15 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
       return Builder.CreateFCmp(PredL, LHS0, RHS0);
   }
 
+  if (IsAnd && stripSignOnlyFPOps(LHS0) == stripSignOnlyFPOps(RHS0)) {
+    // and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
+    // and (fcmp ord x, 0), (fcmp u* fabs(x), inf) -> fcmp o* x, inf
+    if (Value *Left = matchIsFiniteTest(Builder, LHS, RHS))
+      return Left;
+    if (Value *Right = matchIsFiniteTest(Builder, RHS, LHS))
+      return Right;
+  }
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/and-fcmp.ll b/llvm/test/Transforms/InstCombine/and-fcmp.ll
index bbd48c23761c2..affd58f81dffe 100644
--- a/llvm/test/Transforms/InstCombine/and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/and-fcmp.ll
@@ -4614,10 +4614,8 @@ define i1 @intersect_fmf_4(double %a, double %b) {
 define i1 @clang_builtin_isnormal_inf_check(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4629,10 +4627,8 @@ define i1 @clang_builtin_isnormal_inf_check(half %x) {
 define <2 x i1> @clang_builtin_isnormal_inf_check_vector(<2 x half> %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_vector(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord <2 x half> [[X]], zeroinitializer
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge <2 x half> [[FABS_X]], <half 0xH7C00, half 0xH7C00>
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret <2 x i1> [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge <2 x half> [[FABS_X]], <half 0xH7C00, half 0xH7C00>
+; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
 ;
   %fabs.x = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
   %ord = fcmp ord <2 x half> %fabs.x, zeroinitializer
@@ -4644,10 +4640,8 @@ define <2 x i1> @clang_builtin_isnormal_inf_check_vector(<2 x half> %x) {
 define i1 @clang_builtin_isnormal_inf_check_commute(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4659,10 +4653,8 @@ define i1 @clang_builtin_isnormal_inf_check_commute(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_commute_nsz_rhs(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nsz_rhs(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp nsz ord half %fabs.x, 0.0
@@ -4674,10 +4666,8 @@ define i1 @clang_builtin_isnormal_inf_check_commute_nsz_rhs(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_commute_nsz_lhs(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nsz_lhs(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4688,10 +4678,8 @@ define i1 @clang_builtin_isnormal_inf_check_commute_nsz_lhs(half %x) {
 
 define i1 @clang_builtin_isnormal_inf_check_commute_nofabs_ueq(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nofabs_ueq(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq half [[X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %ord = fcmp ord half %x, 0.0
   %cmp = fcmp ueq half %x, 0xH7C00
@@ -4702,10 +4690,8 @@ define i1 @clang_builtin_isnormal_inf_check_commute_nofabs_ueq(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_commute_nsz(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nsz(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nsz oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp nsz ord half %fabs.x, 0.0
@@ -4717,11 +4703,7 @@ define i1 @clang_builtin_isnormal_inf_check_commute_nsz(half %x) {
 ; ugt -> ogt
 define i1 @clang_builtin_isnormal_inf_check_ugt(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ugt(
-; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    ret i1 false
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4734,10 +4716,8 @@ define i1 @clang_builtin_isnormal_inf_check_ugt(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_ult(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ult(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4763,10 +4743,8 @@ define i1 @clang_builtin_isnormal_inf_check_ule(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_ueq(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ueq(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4779,10 +4757,8 @@ define i1 @clang_builtin_isnormal_inf_check_ueq(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_une(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_une(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4879,10 +4855,8 @@ define i1 @clang_builtin_isnormal_inf_check_oeq(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_unnececcary_fabs(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_unnececcary_fabs(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[UEQ:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %x, 0.0
@@ -4909,10 +4883,8 @@ define i1 @clang_builtin_isnormal_inf_check_not_ord(half %x) {
 
 define i1 @clang_builtin_isnormal_inf_check_missing_fabs(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_missing_fabs(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
-; CHECK-NEXT:    [[UEQ:%.*]] = fcmp uge half [[X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[X:%.*]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %x, 0.0
@@ -4952,10 +4924,8 @@ define i1 @clang_builtin_isnormal_inf_check_not_inf(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_nsz_lhs(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_nsz_lhs(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[UEQ:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp nsz ord half %fabs.x, 0.0
@@ -4967,10 +4937,8 @@ define i1 @clang_builtin_isnormal_inf_check_nsz_lhs(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_nsz_rhs(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_nsz_rhs(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -4982,10 +4950,8 @@ define i1 @clang_builtin_isnormal_inf_check_nsz_rhs(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_nsz(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_nsz(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nsz oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp nsz ord half %fabs.x, 0.0
@@ -4996,10 +4962,8 @@ define i1 @clang_builtin_isnormal_inf_check_nsz(half %x) {
 
 define i1 @clang_builtin_isnormal_inf_check_fneg(half %x) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_fneg(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge half [[X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[X:%.*]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fneg.x = fneg half %x
   %ord = fcmp ord half %fneg.x, 0.0
@@ -5011,10 +4975,8 @@ define i1 @clang_builtin_isnormal_inf_check_fneg(half %x) {
 define i1 @clang_builtin_isnormal_inf_check_copysign(half %x, half %y) {
 ; CHECK-LABEL: @clang_builtin_isnormal_inf_check_copysign(
 ; CHECK-NEXT:    [[COPYSIGN_X:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge half [[COPYSIGN_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[COPYSIGN_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %copysign.x = call half @llvm.copysign.f16(half %x, half %y)
   %ord = fcmp ord half %x, 0.0
@@ -5026,10 +4988,8 @@ define i1 @clang_builtin_isnormal_inf_check_copysign(half %x, half %y) {
 define i1 @isnormal_logical_select_0(half %x) {
 ; CHECK-LABEL: @isnormal_logical_select_0(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP_INF:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP_INF]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -5041,10 +5001,8 @@ define i1 @isnormal_logical_select_0(half %x) {
 define i1 @isnormal_logical_select_1(half %x) {
 ; CHECK-LABEL: @isnormal_logical_select_1(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP_INF:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP_INF]], i1 [[ORD]], i1 false
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0
@@ -5056,10 +5014,8 @@ define i1 @isnormal_logical_select_1(half %x) {
 define i1 @isnormal_logical_select_0_fmf0(half %x) {
 ; CHECK-LABEL: @isnormal_logical_select_0_fmf0(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp reassoc nsz arcp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP_INF:%.*]] = fcmp reassoc nsz arcp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP_INF]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp reassoc nsz arcp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp nsz arcp reassoc ord half %fabs.x, 0.0
@@ -5071,10 +5027,8 @@ define i1 @isnormal_logical_select_0_fmf0(half %x) {
 define i1 @isnormal_logical_select_0_fmf1(half %x) {
 ; CHECK-LABEL: @isnormal_logical_select_0_fmf1(
 ; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CMP_INF:%.*]] = fcmp reassoc nsz arcp uge half [[FABS_X]], 0xH7C00
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[CMP_INF]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs.x = call half @llvm.fabs.f16(half %x)
   %ord = fcmp ord half %fabs.x, 0.0

diff  --git a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
index 308b8913a3d01..15e48ae4185b1 100644
--- a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
@@ -802,10 +802,8 @@ define i1 @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(half %x) {
 define i1 @is_finite_and_ord(half %x) {
 ; CHECK-LABEL: @is_finite_and_ord(
 ; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[IS_FINITE:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[IS_FINITE]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs = call half @llvm.fabs.f16(half %x)
   %is.finite = fcmp ueq half %fabs, 0xH7C00
@@ -926,12 +924,10 @@ define i1 @oeq_isinf_and_ord(half %x) {
 define i1 @isnormal_or_zero(half %x) #0 {
 ; CHECK-LABEL: @isnormal_or_zero(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[ISEQ:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
-; CHECK-NEXT:    [[FABS:%.*]] = tail call half @llvm.fabs.f16(half [[X]])
-; CHECK-NEXT:    [[ISINF:%.*]] = fcmp ult half [[FABS]], 0xH7C00
+; CHECK-NEXT:    [[FABS:%.*]] = tail call half @llvm.fabs.f16(half [[X:%.*]])
 ; CHECK-NEXT:    [[ISNORMAL:%.*]] = fcmp uge half [[FABS]], 0xH0400
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ISEQ]], [[ISINF]]
-; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[ISNORMAL]], [[AND]]
+; CHECK-NEXT:    [[TMP0:%.*]] = fcmp olt half [[FABS]], 0xH7C00
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[ISNORMAL]], [[TMP0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[X]], 0xH0000
 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = or i1 [[CMP]], [[AND1]]
 ; CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
@@ -1586,10 +1582,8 @@ define i1 @oge_eq_inf_or_uno(half %x) #0 {
 define i1 @ult_fabs_eq_inf_and_ord(half %x) #0 {
 ; CHECK-LABEL: @ult_fabs_eq_inf_and_ord(
 ; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT:    [[ULT_FABS_INF:%.*]] = fcmp ult half [[FABS]], 0xH7C00
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ULT_FABS_INF]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt half [[FABS]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %fabs = call half @llvm.fabs.f16(half %x)
   %ult.fabs.inf = fcmp ult half %fabs, 0xH7C00
@@ -1600,10 +1594,8 @@ define i1 @ult_fabs_eq_inf_and_ord(half %x) #0 {
 
 define i1 @ult_eq_inf_and_ord(half %x) #0 {
 ; CHECK-LABEL: @ult_eq_inf_and_ord(
-; CHECK-NEXT:    [[ULT_FABS_INF:%.*]] = fcmp ult half [[X:%.*]], 0xH7C00
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ULT_FABS_INF]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt half [[X:%.*]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %ult.fabs.inf = fcmp ult half %x, 0xH7C00
   %ord = fcmp ord half %x, 0xH0000
@@ -1769,10 +1761,8 @@ define i1 @une_neginfinity_or_ord(half %x) #0 {
 ; -> ~(nan | ninf)
 define i1 @une_neginfinity_and_ord(half %x) #0 {
 ; CHECK-LABEL: @une_neginfinity_and_ord(
-; CHECK-NEXT:    [[UNE_NEG_INFINITY:%.*]] = fcmp une half [[X:%.*]], 0xHFC00
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
-; CHECK-NEXT:    [[CLASS:%.*]] = and i1 [[UNE_NEG_INFINITY]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[CLASS]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one half [[X:%.*]], 0xHFC00
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %une.neg.infinity = fcmp une half %x, 0xHFC00
   %ord = fcmp ord half %x, 0.0


        


More information about the llvm-commits mailing list