Index: llvm/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/include/llvm/IR/InstrTypes.h +++ llvm/include/llvm/IR/InstrTypes.h @@ -833,6 +833,17 @@ 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. Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1205,6 +1205,49 @@ 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 matchIsNaN(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, y +/// and (fcmp ord x, 0), (fcmp u* fabs(x), inf) -> fcmp o* x, y +/// +/// Clang emits this pattern for doing an isfinite check in __builtin_isnormal. +static Value *matchOrdAndUnorderedCmpInf(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 (!matchIsNaN(PredL, LHS0, LHS1) || + !matchUnorderedInfCompare(PredR, RHS0, RHS1)) + return nullptr; + + IRBuilder<>::FastMathFlagGuard FMFG(Builder); + FastMathFlags FMF = LHS->getFastMathFlags(); + FMF &= RHS->getFastMathFlags(); + Builder.setFastMathFlags(FMF); + + FCmpInst::Predicate OrderedPred = FCmpInst::getOrderedPredicate(PredR); + return getFCmpValue(OrderedPred, RHS0, RHS1, Builder); +} + Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS, bool IsAnd, bool IsLogicalSelect) { Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1); @@ -1263,6 +1306,13 @@ return Builder.CreateFCmp(PredL, LHS0, RHS0); } + if (IsAnd && stripSignOnlyFPOps(LHS0) == stripSignOnlyFPOps(RHS0)) { + if (Value *Left = matchOrdAndUnorderedCmpInf(Builder, LHS, RHS)) + return Left; + if (Value *Right = matchOrdAndUnorderedCmpInf(Builder, RHS, LHS)) + return Right; + } + return nullptr; } Index: llvm/test/Transforms/InstCombine/and-fcmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/and-fcmp.ll +++ llvm/test/Transforms/InstCombine/and-fcmp.ll @@ -4614,10 +4614,8 @@ 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 <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 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_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_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_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_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 @@ ; 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_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_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_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_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_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_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_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(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_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_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 @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_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_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_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 Index: llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll +++ llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll @@ -802,10 +802,8 @@ 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 @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 @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_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 @@ ; -> ~(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 Index: llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll =================================================================== --- llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll +++ llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll @@ -3,10 +3,8 @@ define i1 @fcmp_ord_and_uno(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_uno( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UNO:%.*]] = fcmp uno half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UNO]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp ord half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %uno = fcmp uno half %x, %y @@ -16,10 +14,8 @@ define i1 @fcmp_ord_and_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %ueq = fcmp ueq half %x, %y @@ -29,10 +25,8 @@ define i1 @fcmp_ord_and_ugt(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ugt( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UGT:%.*]] = fcmp ugt half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UGT]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %ugt = fcmp ugt half %x, %y @@ -42,10 +36,8 @@ define i1 @fcmp_ord_and_uge(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_uge( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UGE:%.*]] = fcmp uge half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UGE]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %uge = fcmp uge half %x, %y @@ -55,10 +47,8 @@ define i1 @fcmp_ord_and_ult(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ult( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[ULT]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %ult = fcmp ult half %x, %y @@ -68,10 +58,8 @@ define i1 @fcmp_ord_and_ule(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ule( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[ULE:%.*]] = fcmp ule half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[ULE]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp ole half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %ule = fcmp ule half %x, %y @@ -81,10 +69,8 @@ define i1 @fcmp_ord_and_une(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_une( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UNE:%.*]] = fcmp une half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UNE]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp one half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %une = fcmp une half %x, %y @@ -105,10 +91,8 @@ define <2 x i1> @fcmp_ord_and_ueq_vector(<2 x half> %x, <2 x half> %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq_vector( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord <2 x half> [[X:%.*]], zeroinitializer -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq <2 x half> [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]] -; CHECK-NEXT: ret <2 x i1> [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq <2 x half> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; %ord = fcmp ord <2 x half> %x, zeroinitializer %ueq = fcmp ueq <2 x half> %x, %y @@ -167,10 +151,8 @@ ; CHECK-LABEL: @fcmp_ord_and_ueq_commute1( ; CHECK-NEXT: [[X:%.*]] = call half @foo() ; CHECK-NEXT: [[Y:%.*]] = call half @foo() -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %x = call half @foo() %y = call half @foo() @@ -182,10 +164,8 @@ define i1 @fcmp_oeq_x_x_and_ult(half %x, half %y) { ; CHECK-LABEL: @fcmp_oeq_x_x_and_ult( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[ULT]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp oeq half %x, %x ; noncanonical ordered %ult = fcmp ult half %x, %y @@ -195,10 +175,8 @@ define i1 @fcmp_ord_and_ueq_preserve_flags(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_flags( -; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp nsz oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp nsz ord half %x, 0.0 %ueq = fcmp nsz ueq half %x, %y @@ -208,10 +186,8 @@ define i1 @fcmp_ord_and_ueq_preserve_subset_flags0(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags0( -; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ninf nsz ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp nsz oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp nsz ord half %x, 0.0 %ueq = fcmp ninf nsz ueq half %x, %y @@ -221,10 +197,8 @@ define i1 @fcmp_ord_and_ueq_preserve_subset_flags1(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags1( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ninf nsz ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp nsz oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ninf nsz ord half %x, 0.0 %ueq = fcmp nsz ueq half %x, %y @@ -234,10 +208,8 @@ define i1 @fcmp_ord_and_ueq_flags_lhs(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq_flags_lhs( -; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp nsz ord half %x, 0.0 %ueq = fcmp ueq half %x, %y @@ -247,10 +219,8 @@ define i1 @fcmp_ord_and_ueq_flags_rhs(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_ueq_flags_rhs( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %ord = fcmp ord half %x, 0.0 %ueq = fcmp nsz ueq half %x, %y @@ -262,10 +232,8 @@ define i1 @fcmp_ord_and_fabs_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_fabs_ueq( ; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[FABS_X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fabs.x = call half @llvm.fabs.f16(half %x) %ord = fcmp ord half %x, 0.0 @@ -276,10 +244,8 @@ define i1 @fcmp_ord_fabs_and_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_fabs_and_ueq( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fabs.x = call half @llvm.fabs.f16(half %x) %ord = fcmp ord half %fabs.x, 0.0 @@ -329,10 +295,8 @@ define <2 x i1> @fcmp_ord_and_fabs_ueq_vector(<2 x half> %x, <2 x half> %y) { ; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_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: [[UEQ:%.*]] = fcmp ueq <2 x half> [[FABS_X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]] -; CHECK-NEXT: ret <2 x i1> [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq <2 x half> [[FABS_X]], [[Y:%.*]] +; 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> %x, zeroinitializer @@ -344,10 +308,8 @@ define i1 @fcmp_ord_fabs_and_fabs_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_fabs_and_fabs_ueq( ; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[FABS_X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fabs.x = call half @llvm.fabs.f16(half %x) %ord = fcmp ord half %fabs.x, 0.0 @@ -359,10 +321,8 @@ define i1 @fcmp_ord_and_fneg_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_and_fneg_ueq( ; CHECK-NEXT: [[FNEG_X:%.*]] = fneg half [[X:%.*]] -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FNEG_X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[FNEG_X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fneg.x = fneg half %x %ord = fcmp ord half %x, 0.0 @@ -373,10 +333,8 @@ define i1 @fcmp_ord_fneg_and_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_fneg_and_ueq( -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fneg.x = fneg half %x %ord = fcmp ord half %fneg.x, 0.0 @@ -388,10 +346,8 @@ define i1 @fcmp_ord_fneg_and_fneg_ueq(half %x, half %y) { ; CHECK-LABEL: @fcmp_ord_fneg_and_fneg_ueq( ; CHECK-NEXT: [[FNEG_X:%.*]] = fneg half [[X:%.*]] -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FNEG_X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[FNEG_X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fneg.x = fneg half %x %ord = fcmp ord half %fneg.x, 0.0 @@ -404,10 +360,8 @@ ; CHECK-LABEL: @fcmp_ord_and_fneg_fabs_ueq( ; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) ; CHECK-NEXT: [[FNEG_FABS_X:%.*]] = fneg half [[FABS_X]] -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FNEG_FABS_X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[FNEG_FABS_X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %fabs.x = call half @llvm.fabs.f16(half %x) %fneg.fabs.x = fneg half %fabs.x @@ -420,10 +374,8 @@ define i1 @fcmp_ord_and_copysign_ueq(half %x, half %y, half %z) { ; CHECK-LABEL: @fcmp_ord_and_copysign_ueq( ; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[COPYSIGN_X_Y]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) %ord = fcmp ord half %x, 0.0 @@ -434,11 +386,8 @@ define i1 @fcmp_copysign_ord_and_ueq(half %x, half %y, half %z) { ; CHECK-LABEL: @fcmp_copysign_ord_and_ueq( -; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[COPYSIGN_X_Y]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) %ord = fcmp ord half %copysign.x.y, 0.0 @@ -450,10 +399,8 @@ define i1 @fcmp_ord_and_copysign_ueq_commute(half %x, half %y, half %z) { ; CHECK-LABEL: @fcmp_ord_and_copysign_ueq_commute( ; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[COPYSIGN_X_Y]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) %ord = fcmp ord half %x, 0.0 @@ -465,10 +412,8 @@ define i1 @fcmp_ord_and_copysign_fneg_ueq(half %x, half %y, half %z) { ; CHECK-LABEL: @fcmp_ord_and_copysign_fneg_ueq( ; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) -; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 -; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq half [[COPYSIGN_X_Y]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %x.fneg = fneg half %x %copysign.x.y = call half @llvm.copysign.f16(half %x.fneg, half %z)