diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3703,6 +3703,13 @@ break; } } + + // LHS == Inf + if (Pred == FCmpInst::FCMP_OEQ && isKnownNeverInfinity(LHS, Q.TLI)) + return getFalse(RetTy); + // LHS != Inf + if (Pred == FCmpInst::FCMP_UNE && isKnownNeverInfinity(LHS, Q.TLI)) + return getTrue(RetTy); } if (C->isNegative() && !C->isNegZero()) { assert(!C->isNaN() && "Unexpected NaN constant!"); diff --git a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll --- a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll +++ b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll @@ -1041,9 +1041,7 @@ define i1 @is_infinite(float %x) { ; CHECK-LABEL: @is_infinite( -; CHECK-NEXT: [[XABS:%.*]] = call ninf float @llvm.fabs.f32(float [[X:%.*]]) -; CHECK-NEXT: [[R:%.*]] = fcmp oeq float [[XABS]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %xabs = call ninf float @llvm.fabs.f32(float %x) %r = fcmp oeq float %xabs, 0x7FF0000000000000 @@ -1052,15 +1050,15 @@ define <2 x i1> @is_infinite_neg(<2 x float> %x) { ; CHECK-LABEL: @is_infinite_neg( -; CHECK-NEXT: [[X42:%.*]] = fadd ninf <2 x float> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = fcmp oeq <2 x float> [[X42]], -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %x42 = fadd ninf <2 x float> %x, %r = fcmp oeq <2 x float> %x42, ret <2 x i1> %r } +; Negative test - but this could be reduced to 'uno' outside of instsimplify. + define i1 @is_infinite_or_nan(float %x) { ; CHECK-LABEL: @is_infinite_or_nan( ; CHECK-NEXT: [[X42:%.*]] = fadd ninf float [[X:%.*]], 4.200000e+01 @@ -1074,10 +1072,7 @@ define i1 @is_finite_or_nan(i1 %c, double %x) { ; CHECK-LABEL: @is_finite_or_nan( -; CHECK-NEXT: [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]] -; CHECK-NEXT: [[S:%.*]] = select i1 [[C:%.*]], double 4.200000e+01, double [[XX]] -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[S]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %xx = fmul ninf double %x, %x %s = select i1 %c, double 42.0, double %xx @@ -1087,15 +1082,15 @@ define <2 x i1> @is_finite_or_nan_commute(<2 x i8> %x) { ; CHECK-LABEL: @is_finite_or_nan_commute( -; CHECK-NEXT: [[CAST:%.*]] = uitofp <2 x i8> [[X:%.*]] to <2 x float> -; CHECK-NEXT: [[R:%.*]] = fcmp une <2 x float> , [[CAST]] -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> ; %cast = uitofp <2 x i8> %x to <2 x float> %r = fcmp une <2 x float> , %cast ret <2 x i1> %r } +; Negative test - but this could be reduced to 'ord' outside of instsimplify. + define i1 @is_finite_and_ordered(double %x) { ; CHECK-LABEL: @is_finite_and_ordered( ; CHECK-NEXT: [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]]