diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index af8227650dc19..8ff71de9dca78 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4458,6 +4458,22 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, break; } + case Instruction::FMul: { + KnownFPClass KnownLHS, KnownRHS; + computeKnownFPClass(Op->getOperand(1), DemandedElts, fcNan | fcInf, + KnownRHS, Depth + 1, Q, TLI); + if (KnownRHS.isKnownNeverNaN() && KnownRHS.isKnownNeverInfinity()) { + computeKnownFPClass(Op->getOperand(0), DemandedElts, fcNan | fcInf, + KnownLHS, Depth + 1, Q, TLI); + + // Zero multiplied with infinity produces NaN. + // FIXME: If neither side can be zero fmul never produces NaN. + if (KnownLHS.isKnownNeverNaN() && KnownLHS.isKnownNeverInfinity()) + Known.knownNot(fcNan); + } + + break; + } case Instruction::SIToFP: case Instruction::UIToFP: { // Cannot produce nan diff --git a/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll b/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll index a129c7ba1c584..3b433dd547aa0 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll @@ -52,7 +52,7 @@ define float @ret_fmul_dynamic_nonan_nozero__nonan_nozero(float nofpclass(nan ze } define float @ret_fmul_ieee_nonan_noinf__nonan_noinf(float nofpclass(nan inf) %arg0, float nofpclass(nan inf) %arg1) #0 { -; CHECK-LABEL: define float @ret_fmul_ieee_nonan_noinf__nonan_noinf +; CHECK-LABEL: define nofpclass(nan) float @ret_fmul_ieee_nonan_noinf__nonan_noinf ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FMUL]] diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 55834a70fe6c7..ba983d4768bea 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1575,6 +1575,23 @@ TEST_F(ComputeKnownFPClassTest, FSub) { expectKnownFPClass(fcAllFlags, std::nullopt, A5); } +TEST_F(ComputeKnownFPClassTest, FMul) { + parseAssembly( + "define float @test(float nofpclass(nan inf) %nnan.ninf, float nofpclass(nan) %nnan, float nofpclass(qnan) %no.qnan, float %unknown) {\n" + " %A = fmul float %nnan.ninf, %nnan.ninf" + " %A2 = fmul float %nnan.ninf, %nnan" + " %A3 = fmul float %nnan, %nnan.ninf" + " %A4 = fmul float %nnan.ninf, %no.qnan" + " %A5 = fmul float %nnan, %nnan" + " ret float %A\n" + "}\n"); + expectKnownFPClass(fcFinite | fcInf, std::nullopt, A); + expectKnownFPClass(fcAllFlags, std::nullopt, A2); + expectKnownFPClass(fcAllFlags, std::nullopt, A3); + expectKnownFPClass(fcAllFlags, std::nullopt, A4); + expectKnownFPClass(fcAllFlags, std::nullopt, A5); +} + TEST_F(ValueTrackingTest, isNonZeroRecurrence) { parseAssembly(R"( define i1 @test(i8 %n, i8 %r) {