[llvm] InstCombine: Compute fp class when simplifying with multiple uses (PR #174086)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 31 03:47:36 PST 2025


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

Fall back on reporting the known fp class even if we aren't simplifying
the value.

>From 5887bb05feea0a8ba71c913e91a737e49bf374e9 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 31 Dec 2025 12:45:39 +0100
Subject: [PATCH] InstCombine: Compute fp class when simplifying with multiple
 uses

Fall back on reporting the known fp class even if we aren't simplifying
the value.
---
 .../InstCombineSimplifyDemanded.cpp           |  4 +++-
 .../InstCombine/simplify-demanded-fpclass.ll  | 21 +++++++++++++++++--
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 85672cdfe1377..19b98080d628a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2053,8 +2053,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
     return FoldedToConst == V ? nullptr : FoldedToConst;
   }
 
-  if (!I->hasOneUse())
+  if (!I->hasOneUse()) {
+    Known = computeKnownFPClass(V, DemandedMask, CxtI, Depth + 1);
     return nullptr;
+  }
 
   if (auto *FPOp = dyn_cast<FPMathOperator>(I)) {
     if (FPOp->hasNoNaNs())
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index a7ff967d3123b..c28b5967303c8 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -1137,8 +1137,7 @@ define nofpclass(inf) float @ret_nofpclass_inf__select_assumed_call_result_only_
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MUST_BE_INF]])
 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_INF]])
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MUST_BE_INF]], float [[Y]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[Y]]
 ;
   %must.be.inf = call float @extern()
   %fabs = call float @llvm.fabs.f32(float %must.be.inf)
@@ -1340,3 +1339,21 @@ define nofpclass(ninf) float @ret_nofpclass_ninf__maxnum_pinf(i1 %cond, float %x
   %max = call float @llvm.maximumnum.f32(float %x, float 0x7FF0000000000000)
   ret float %max
 }
+
+declare nofpclass(inf norm sub zero) float @returns_nan()
+
+; %nan has multiple uses, but we should still know what class is is
+; %allowing this to fold to a single select.
+define nofpclass(nan) float @known_class_multiple_uses(i1 %cond0, i1 %cond1, i1 %cond2, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(nan) float @known_class_multiple_uses
+; CHECK-SAME: (i1 [[COND0:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[NAN:%.*]] = call float @returns_nan()
+; CHECK-NEXT:    [[SELECT2:%.*]] = select i1 [[COND2]], float [[UNKNOWN0]], float [[UNKNOWN1]]
+; CHECK-NEXT:    ret float [[SELECT2]]
+;
+  %nan = call float @returns_nan()
+  %select0 = select i1 %cond0, float %unknown0, float %nan
+  %select1 = select i1 %cond1, float %nan, float %unknown1
+  %select2 = select i1 %cond2, float %select0, float %select1
+  ret float %select2
+}



More information about the llvm-commits mailing list