diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index cd4d6aefa7d4c6..56c59b2d5692f6 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(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 3e39dc673d79e0..5634008b91fc60 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 bbd48c23761c29..affd58f81dffe5 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]], -; 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]], +; 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 308b8913a3d01e..15e48ae4185b13 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