Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -3879,9 +3879,11 @@ return {nullptr, fcNone}; if (ConstRHS->isZero()) { - // Compares with fcNone are only exactly equal to fcZero if input denormals are - // not flushed. - if (FCmpInst::isEquality(Pred) && !inputDenormalIsIEEE(F, LHS->getType())) + // Compares with fcNone are only exactly equal to fcZero if input denormals + // are not flushed. + // TODO: Handle DAZ by expanding masks to cover subnormal cases. + if (Pred != FCmpInst::FCMP_ORD && Pred != FCmpInst::FCMP_UNO && + !inputDenormalIsIEEE(F, LHS->getType())) return {nullptr, fcNone}; switch (Pred) { @@ -3899,6 +3901,18 @@ return {LHS, ~fcNan}; case FCmpInst::FCMP_UNO: return {LHS, fcNan}; + case FCmpInst::FCMP_OGE: + // x >= 0 + return {LHS, fcPositive | fcNegZero}; + case FCmpInst::FCMP_UGE: + // isnan(x) || x >= 0 + return {LHS, fcPositive | fcNegZero | fcNan}; + case FCmpInst::FCMP_OLE: + // x <= 0 + return {LHS, fcNegative | fcPosZero}; + case FCmpInst::FCMP_ULT: + // isnan(x) || x <= 0 + return {LHS, fcNegative | fcPosZero | fcNan}; default: break; } 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 @@ -1908,9 +1908,7 @@ define i1 @fcmp_ueq_neginf_or_oge_zero_f16(half %x) { ; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16( -; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00 -; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000 -; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]] +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 999) ; CHECK-NEXT: ret i1 [[CLASS]] ; %cmpinf = fcmp ueq half %x, 0xHFC00 @@ -1921,9 +1919,7 @@ define i1 @fcmp_oeq_neginf_or_oge_zero_f16(half %x) { ; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16( -; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 -; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000 -; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]] +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 996) ; CHECK-NEXT: ret i1 [[CLASS]] ; %cmpinf = fcmp oeq half %x, 0xHFC00 @@ -1960,9 +1956,7 @@ define i1 @fcmp_ueq_posinf_or_ole_zero_f16(half %x) { ; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16( -; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00 -; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000 -; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]] +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639) ; CHECK-NEXT: ret i1 [[CLASS]] ; %cmpinf = fcmp ueq half %x, 0xH7C00 @@ -1973,9 +1967,7 @@ define i1 @fcmp_oeq_posinf_or_ole_zero_f16(half %x) { ; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16( -; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 -; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000 -; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]] +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 636) ; CHECK-NEXT: ret i1 [[CLASS]] ; %cmpinf = fcmp oeq half %x, 0xH7C00 @@ -2064,9 +2056,7 @@ define i1 @fcmp_ueq_posinf_or_ult_zero_f16(half %x) { ; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16( -; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00 -; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000 -; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]] +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639) ; CHECK-NEXT: ret i1 [[CLASS]] ; %cmpinf = fcmp ueq half %x, 0xH7C00 @@ -2077,9 +2067,7 @@ define i1 @fcmp_oeq_posinf_or_ult_zero_f16(half %x) { ; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16( -; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 -; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000 -; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]] +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639) ; CHECK-NEXT: ret i1 [[CLASS]] ; %cmpinf = fcmp oeq half %x, 0xH7C00