[llvm] ValueTracking: Revert noundef checks in computeKnownFPClass for fmul/fma (PR #178850)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 30 01:28:18 PST 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/178850

This functionally reverts fd5cfcc41311c6287e9dc408b8aae499501660e1 and
35ce17b6f6ca5dd321af8e6763554b10824e4ac4.

This was correct and necessary, but is causing performance regressions
since isGuaranteedNotToBeUndef is apparently not smart enough to detect
through recurrences. Revert this for the release branch.

Also the test coverage was inadequate for the fma case, so add a new
case which changes with and without the check.

>From d0ed0ac295442a61f243a7818ccf0530adf9eb05 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 29 Jan 2026 23:57:55 +0100
Subject: [PATCH] ValueTracking: Revert noundef checks in computeKnownFPClass
 for fmul/fma

This functionally reverts fd5cfcc41311c6287e9dc408b8aae499501660e1 and
35ce17b6f6ca5dd321af8e6763554b10824e4ac4.

This was correct and necessary, but is causing performance regressions
since isGuaranteedNotToBeUndef is apparently not smart enough to detect
through recurrences. Revert this for the release branch.

Also the test coverage was inadequate for the fma case, so add a new
case which changes with and without the check.
---
 llvm/lib/Analysis/ValueTracking.cpp           |  9 ++++---
 .../Transforms/Attributor/nofpclass-fma.ll    | 24 +++++++++++++++++++
 .../Transforms/Attributor/nofpclass-fmul.ll   |  2 +-
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d69c918737212..b0d640e33cc28 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5136,9 +5136,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
       if ((InterestedClasses & fcNegative) == fcNone)
         break;
 
-      if (II->getArgOperand(0) == II->getArgOperand(1) &&
-          isGuaranteedNotToBeUndef(II->getArgOperand(0), Q.AC, Q.CxtI, Q.DT,
-                                   Depth + 1)) {
+      // FIXME: This should check isGuaranteedNotToBeUndef
+      if (II->getArgOperand(0) == II->getArgOperand(1)) {
         KnownFPClass KnownSrc, KnownAddend;
         computeKnownFPClass(II->getArgOperand(2), DemandedElts,
                             InterestedClasses, KnownAddend, Q, Depth + 1);
@@ -5606,8 +5605,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
           : DenormalMode::getDynamic();
 
     // X * X is always non-negative or a NaN.
-    if (Op->getOperand(0) == Op->getOperand(1) &&
-        isGuaranteedNotToBeUndef(Op->getOperand(0), Q.AC, Q.CxtI, Q.DT)) {
+    // FIXME: Should check isGuaranteedNotToBeUndef
+    if (Op->getOperand(0) == Op->getOperand(1)) {
       KnownFPClass KnownSrc;
       computeKnownFPClass(Op->getOperand(0), DemandedElts, fcAllFlags, KnownSrc,
                           Q, Depth + 1);
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fma.ll b/llvm/test/Transforms/Attributor/nofpclass-fma.ll
index 0f376b9834496..0284b97181177 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fma.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fma.ll
@@ -78,6 +78,30 @@ define float @ret_fmuladd_different_same_arg_positive_addend(float noundef %arg0
   ret float %call
 }
 
+define half @ret_fma__square_maybe_undef__pos2(half %unknown) {
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) half @ret_fma__square_maybe_undef__pos2
+; CHECK-SAME: (half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[POS2:%.*]] = call half @returns_positive_or_nan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call nofpclass(ninf nsub nnorm) half @llvm.fma.f16(half [[UNKNOWN]], half [[UNKNOWN]], half [[POS2]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %pos2 = call half @returns_positive_or_nan()
+  %result = call half @llvm.fma.f16(half %unknown, half %unknown, half %pos2)
+  ret half %result
+}
+
+define half @ret_fma__square__pos2(half noundef %unknown) {
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) half @ret_fma__square__pos2
+; CHECK-SAME: (half noundef [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[POS2:%.*]] = call half @returns_positive_or_nan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call nofpclass(ninf nsub nnorm) half @llvm.fma.f16(half noundef [[UNKNOWN]], half noundef [[UNKNOWN]], half [[POS2]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %pos2 = call half @returns_positive_or_nan()
+  %result = call half @llvm.fma.f16(half %unknown, half %unknown, half %pos2)
+  ret half %result
+}
+
 ;---------------------------------------------------------------------
 ; Sign bit permutations
 ;---------------------------------------------------------------------
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fmul.ll b/llvm/test/Transforms/Attributor/nofpclass-fmul.ll
index edf8d196960d3..a3704c41ff85b 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fmul.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fmul.ll
@@ -25,7 +25,7 @@ define float @ret_fmul_square_f32(float noundef %arg) {
 }
 
 define float @ret_fmul_square_f32_maybe_undef(float %arg) {
-; CHECK-LABEL: define float @ret_fmul_square_f32_maybe_undef(
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_fmul_square_f32_maybe_undef(
 ; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {
 ; CHECK-NEXT:    [[FMUL:%.*]] = fmul float [[ARG]], [[ARG]]
 ; CHECK-NEXT:    ret float [[FMUL]]



More information about the llvm-commits mailing list