Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4275,11 +4275,14 @@ KnownNotFromFlags |= Arg->getNoFPClass(); const Operator *Op = dyn_cast(V); - if (const FPMathOperator *FPOp = dyn_cast_or_null(Op)) { - if (FPOp->hasNoNaNs()) - KnownNotFromFlags |= fcNan; - if (FPOp->hasNoInfs()) - KnownNotFromFlags |= fcInf; + + if (Q.IIQ.UseInstrInfo) { + if (const FPMathOperator *FPOp = dyn_cast_or_null(Op)) { + if (FPOp->hasNoNaNs()) + KnownNotFromFlags |= fcNan; + if (FPOp->hasNoInfs()) + KnownNotFromFlags |= fcInf; + } } if (Q.AC) { Index: llvm/unittests/Analysis/ValueTrackingTest.cpp =================================================================== --- llvm/unittests/Analysis/ValueTrackingTest.cpp +++ llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1964,6 +1964,59 @@ } } +/// Test that the UseInstrInfo parameter is respected. +TEST_F(ComputeKnownFPClassTest, RespectIgnoreFlags) { + parseAssembly( + "declare float @func()\n" + "define float @test(i1 %cond, float %arg0, float %arg1) {\n" + " %A = fadd nnan float %arg0, %arg1\n" + " %A2 = fmul ninf float %arg0, %arg1\n" + " %A3 = call nofpclass(inf nan) float @func()\n" + " ret float %A\n" + "}\n"); + + { + KnownFPClass UseInstrInfoNoNaN = + computeKnownFPClass(A, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); + EXPECT_EQ(~fcNan, UseInstrInfoNoNaN.KnownFPClasses); + EXPECT_EQ(std::nullopt, UseInstrInfoNoNaN.SignBit); + } + + { + KnownFPClass UseInstrInfoNoInf = + computeKnownFPClass(A2, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); + EXPECT_EQ(~fcInf, UseInstrInfoNoInf.KnownFPClasses); + EXPECT_EQ(std::nullopt, UseInstrInfoNoInf.SignBit); + } + + { + KnownFPClass NoUseInstrInfoNoNaN = + computeKnownFPClass(A, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(fcAllFlags, NoUseInstrInfoNoNaN.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrInfoNoNaN.SignBit); + } + + { + KnownFPClass NoUseInstrInfoNoInf = + computeKnownFPClass(A2, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(fcAllFlags, NoUseInstrInfoNoInf.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrInfoNoInf.SignBit); + } + + // Still looks at nofpclass attribute + { + KnownFPClass NoUseInstrUsesOther = + computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(~(fcInf|fcNan), NoUseInstrUsesOther.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrUsesOther.SignBit); + } +} + TEST_F(ValueTrackingTest, isNonZeroRecurrence) { parseAssembly(R"( define i1 @test(i8 %n, i8 %r) {