Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -3570,6 +3570,10 @@ } if (C->isZero()) { switch (Pred) { + case FCmpInst::FCMP_OGE: + if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getTrue(RetTy); + break; case FCmpInst::FCMP_UGE: if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) return getTrue(RetTy); Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5435,7 +5435,7 @@ break; // fabs(x) < 0 --> false case FCmpInst::FCMP_OLT: - llvm_unreachable("handled by SimplifyFCmpInst"); + llvm_unreachable("fcmp should have simplified"); // fabs(x) > 0 --> x != 0 case FCmpInst::FCMP_OGT: return new FCmpInst(FCmpInst::FCMP_ONE, CI->getArgOperand(0), RHSC); @@ -5444,6 +5444,7 @@ return new FCmpInst(FCmpInst::FCMP_OEQ, CI->getArgOperand(0), RHSC); // fabs(x) >= 0 --> !isnan(x) case FCmpInst::FCMP_OGE: + assert(!I.hasNoNaNs() && "fcmp should have simplified"); return new FCmpInst(FCmpInst::FCMP_ORD, CI->getArgOperand(0), RHSC); // fabs(x) == 0 --> x == 0 // fabs(x) != 0 --> x != 0 Index: test/Transforms/InstSimplify/floating-point-compare.ll =================================================================== --- test/Transforms/InstSimplify/floating-point-compare.ll +++ test/Transforms/InstSimplify/floating-point-compare.ll @@ -254,9 +254,7 @@ define i1 @orderedLessZeroUIToFP_nnan(i32 %x) { ; CHECK-LABEL: @orderedLessZeroUIToFP_nnan( -; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X:%.*]] to float -; CHECK-NEXT: [[UGE:%.*]] = fcmp nnan oge float [[A]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[UGE]] +; CHECK-NEXT: ret i1 true ; %a = uitofp i32 %x to float %uge = fcmp nnan oge float %a, 0.000000e+00 @@ -265,9 +263,7 @@ define <2 x i1> @orderedLessZeroUIToFP_nnan_vec(<2 x i32> %x) { ; CHECK-LABEL: @orderedLessZeroUIToFP_nnan_vec( -; CHECK-NEXT: [[A:%.*]] = uitofp <2 x i32> [[X:%.*]] to <2 x float> -; CHECK-NEXT: [[UGE:%.*]] = fcmp nnan oge <2 x float> [[A]], zeroinitializer -; CHECK-NEXT: ret <2 x i1> [[UGE]] +; CHECK-NEXT: ret <2 x i1> ; %a = uitofp <2 x i32> %x to <2 x float> %uge = fcmp nnan oge <2 x float> %a, zeroinitializer @@ -294,9 +290,7 @@ define i1 @fabs_nnan_is_positive_or_zero(double %x) { ; CHECK-LABEL: @fabs_nnan_is_positive_or_zero( -; CHECK-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge double [[FABS]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %fabs = tail call double @llvm.fabs.f64(double %x) %cmp = fcmp nnan oge double %fabs, 0.0 @@ -305,9 +299,7 @@ define <2 x i1> @fabs_nnan_is_positive_or_zero_vec(<2 x double> %x) { ; CHECK-LABEL: @fabs_nnan_is_positive_or_zero_vec( -; CHECK-NEXT: [[FABS:%.*]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge <2 x double> [[FABS]], zeroinitializer -; CHECK-NEXT: ret <2 x i1> [[CMP]] +; CHECK-NEXT: ret <2 x i1> ; %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) %cmp = fcmp nnan oge <2 x double> %fabs, zeroinitializer