[llvm] [ValueTracking] Fix incorrect FMF propagation from select to fcmp (PR #195787)
Nathiyaa Sengodan via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 02:32:01 PDT 2026
================
@@ -8922,14 +8921,21 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
SelectPatternNaNBehavior NaNBehavior = SPNB_NA;
bool Ordered = false;
+ auto NaNFMFFor = [&](const Value *Op) {
+ FastMathFlags Res = CmpFMF;
+ if ((Op == TrueVal || Op == FalseVal) && FMF.noNaNs())
+ Res.setNoNaNs(true);
+ return Res;
+ };
+
// When given one NaN and one non-NaN input:
// - maxnum/minnum (C99 fmaxf()/fminf()) return the non-NaN input.
// - A simple C99 (a < b ? a : b) construction will return 'b' (as the
// ordered comparison fails), which could be NaN or non-NaN.
// so here we discover exactly what NaN behavior is required/accepted.
if (CmpInst::isFPPredicate(Pred)) {
- bool LHSSafe = isKnownNonNaN(CmpLHS, FMF);
- bool RHSSafe = isKnownNonNaN(CmpRHS, FMF);
+ bool LHSSafe = isKnownNonNaN(CmpLHS, NaNFMFFor(CmpLHS));
+ bool RHSSafe = isKnownNonNaN(CmpRHS, NaNFMFFor(CmpRHS));
----------------
Nathiyaa-Sengodan wrote:
Currently, FMF parameter her holds the fast-math flags from the **select** instruction, and that is used in isKnownNonNaN to determine whether CmpLHS and CmpRHS are safe.
This becomes problematic when the operands of the **fcmp** and the **select** do not match.
This specific change ensures that the appropriate fast-math context is used when reasoning about LHSSafe and RHSSafe, preventing incorrect propagation of NaN-related assumptions.
Regarding isKnownNonNaN - it is a much simpler helper than isKnownNeverNaN and only handles nnan plus a few obvious constant cases.
If we used isKnownNeverNaN here, we would still need to separately account for the relevant nnan flags from the select and fcmp, because the question here is not only whether the value is globally never NaN, but whether NaN is impossible or poison for this specific compare/select pattern.
https://github.com/llvm/llvm-project/pull/195787
More information about the llvm-commits
mailing list