diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e4e1a2b4707dc..5393be0e247b4 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4760,36 +4760,29 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, if ((InterestedClasses & fcNan) != fcNan) break; - // fcSubnormal is only needed in case of DAZ. - const FPClassTest NeedForNan = fcNan | fcInf | fcZero | fcSubnormal; - KnownFPClass KnownLHS, KnownRHS; - computeKnownFPClass(Op->getOperand(1), DemandedElts, NeedForNan, KnownRHS, + computeKnownFPClass(Op->getOperand(1), DemandedElts, + fcNan | fcInf | fcZero | fcSubnormal, KnownRHS, Depth + 1, Q); - if (!KnownRHS.isKnownNeverNaN()) - break; + if (KnownRHS.isKnownNeverNaN() && + (KnownRHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverZero())) { + computeKnownFPClass(Op->getOperand(0), DemandedElts, + fcNan | fcInf | fcZero, KnownLHS, Depth + 1, Q); + if (!KnownLHS.isKnownNeverNaN()) + break; - computeKnownFPClass(Op->getOperand(0), DemandedElts, NeedForNan, KnownLHS, - Depth + 1, Q); - if (!KnownLHS.isKnownNeverNaN()) - break; + const Function *F = cast(Op)->getFunction(); - // If 0 * +/-inf produces NaN. - if (KnownLHS.isKnownNeverInfinity() && KnownRHS.isKnownNeverInfinity()) { - Known.knownNot(fcNan); - break; + // If neither side can be zero (or nan) fmul never produces NaN. + // TODO: Check operand combinations. + // e.g. fmul nofpclass(inf nan zero), nofpclass(nan) -> nofpclass(nan) + if ((KnownLHS.isKnownNeverInfinity() || + (F && KnownLHS.isKnownNeverLogicalZero(*F, Op->getType()))) && + (KnownRHS.isKnownNeverInfinity() || + (F && KnownRHS.isKnownNeverLogicalZero(*F, Op->getType())))) + Known.knownNot(fcNan); } - const Function *F = cast(Op)->getFunction(); - if (!F) - break; - - if ((KnownRHS.isKnownNeverInfinity() || - KnownLHS.isKnownNeverLogicalZero(*F, Op->getType())) && - (KnownLHS.isKnownNeverInfinity() || - KnownRHS.isKnownNeverLogicalZero(*F, Op->getType()))) - Known.knownNot(fcNan); - break; } case Instruction::FDiv: diff --git a/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll b/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll index fbf6c2e0981fb..bb0179daefbda 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll @@ -62,7 +62,7 @@ define float @ret_fmul_ieee_nonan_noinf__nonan_noinf(float nofpclass(nan inf) %a } define float @ret_fmul_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero) %arg0, float nofpclass(nan inf) %arg1) #0 { -; CHECK-LABEL: define float @ret_fmul_ieee_nonan_nozero__nonan_noinf +; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_nonan_nozero__nonan_noinf ; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] @@ -72,7 +72,7 @@ define float @ret_fmul_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero) } define float @ret_fmul_ieee_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan zero) %arg1) #0 { -; CHECK-LABEL: define float @ret_fmul_ieee_nonan_noinf__nonan_nozero +; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_nonan_noinf__nonan_nozero ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] @@ -285,7 +285,7 @@ define float @ret_fmul_ieee_noinf_nonan__nozero(float nofpclass(inf nan) %arg0, } define float @ret_fmul_ieee_nozero_nonan__noinf_nonan(float nofpclass(zero nan) %arg0, float nofpclass(inf nan) %arg1) { -; CHECK-LABEL: define float @ret_fmul_ieee_nozero_nonan__noinf_nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_nozero_nonan__noinf_nonan ; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] @@ -295,7 +295,7 @@ define float @ret_fmul_ieee_nozero_nonan__noinf_nonan(float nofpclass(zero nan) } define float @ret_fmul_ieee_noinf_nonan__nozero_nonan(float nofpclass(inf nan) %arg0, float nofpclass(zero nan) %arg1) { -; CHECK-LABEL: define float @ret_fmul_ieee_noinf_nonan__nozero_nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_noinf_nonan__nozero_nonan ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] @@ -345,7 +345,7 @@ define float @ret_fmul_ieee_nozero_nonan__nozero_nonan_noinf(float nofpclass(zer } define float @ret_fmul_ieee_nozero_nonan_noinf__nonan(float nofpclass(zero nan inf) %arg0, float nofpclass(nan) %arg1) { -; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_nozero_nonan_noinf__nonan +; CHECK-LABEL: define float @ret_fmul_ieee_nozero_nonan_noinf__nonan ; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] @@ -355,7 +355,7 @@ define float @ret_fmul_ieee_nozero_nonan_noinf__nonan(float nofpclass(zero nan i } define float @ret_fmul_ieee_nonan__nozero_nonan_noinf(float nofpclass(nan) %arg0, float nofpclass(zero nan inf) %arg1) { -; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_nonan__nozero_nonan_noinf +; CHECK-LABEL: define float @ret_fmul_ieee_nonan__nozero_nonan_noinf ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] diff --git a/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll b/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll index 7e9f62158c2de..f0eb263bf0470 100644 --- a/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll +++ b/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll @@ -60,9 +60,9 @@ define internal i1 @simplify_fcmp_ord_frem_callee(double %a, double %b) { ret i1 %cmp } -define i1 @simplify_fcmp_ord_fmul_caller(double nofpclass(zero nan inf) %i0, double nofpclass(zero nan inf) %i1) { +define i1 @simplify_fcmp_ord_fmul_caller(double nofpclass(zero nan) %i0, double nofpclass(zero nan) %i1) { ; CHECK-LABEL: define i1 @simplify_fcmp_ord_fmul_caller -; CHECK-SAME: (double nofpclass(nan inf zero) [[I0:%.*]], double nofpclass(nan inf zero) [[I1:%.*]]) { +; CHECK-SAME: (double nofpclass(nan zero) [[I0:%.*]], double nofpclass(nan zero) [[I1:%.*]]) { ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = fmul double [[I0]], [[I1]] ; CHECK-NEXT: ret i1 true ; diff --git a/llvm/test/Transforms/InstSimplify/known-never-nan.ll b/llvm/test/Transforms/InstSimplify/known-never-nan.ll index 49a48ae42d064..8583d9733d72d 100644 --- a/llvm/test/Transforms/InstSimplify/known-never-nan.ll +++ b/llvm/test/Transforms/InstSimplify/known-never-nan.ll @@ -559,10 +559,7 @@ unwind: ; This should not fold to false because fmul 0 * inf = nan define i1 @issue63316(i64 %arg) { ; CHECK-LABEL: @issue63316( -; CHECK-NEXT: [[SITOFP:%.*]] = sitofp i64 [[ARG:%.*]] to float -; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[SITOFP]], 0x7FF0000000000000 -; CHECK-NEXT: [[FCMP:%.*]] = fcmp uno float [[FMUL]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[FCMP]] +; CHECK-NEXT: ret i1 false ; %sitofp = sitofp i64 %arg to float %fmul = fmul float %sitofp, 0x7FF0000000000000 @@ -572,10 +569,7 @@ define i1 @issue63316(i64 %arg) { define i1 @issue63316_commute(i64 %arg) { ; CHECK-LABEL: @issue63316_commute( -; CHECK-NEXT: [[SITOFP:%.*]] = sitofp i64 [[ARG:%.*]] to float -; CHECK-NEXT: [[FMUL:%.*]] = fmul float 0x7FF0000000000000, [[SITOFP]] -; CHECK-NEXT: [[FCMP:%.*]] = fcmp uno float [[FMUL]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[FCMP]] +; CHECK-NEXT: ret i1 false ; %sitofp = sitofp i64 %arg to float %fmul = fmul float 0x7FF0000000000000, %sitofp