[llvm] [DAG] visitIS_FPCLASS - fold to constant when result is fully determined by KnownFPClass (PR #193737)

Xinlong Chen via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 23 19:08:29 PDT 2026


https://github.com/Xinlong-Chen updated https://github.com/llvm/llvm-project/pull/193737

>From 5425be0a3b5266c993d3b565f658ae899b3277cc Mon Sep 17 00:00:00 2001
From: xinlongchen <xinlongchen at tencent.com>
Date: Thu, 23 Apr 2026 21:07:10 +0800
Subject: [PATCH 1/2] [DAG] visitIS_FPCLASS - fold to constant when result is
 fully determined by KnownFPClass

---
 llvm/test/CodeGen/RISCV/combine-is_fpclass.ll | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
index 71621b8837d6b..d325f9563f6c3 100644
--- a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
+++ b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
@@ -186,6 +186,19 @@ define i1 @extract_scalable_fabs_isneg(<vscale x 4 x float> %a0) nounwind {
   ret i1 %res
 }
 
+define i1 @fabs_is_nonneg_or_nan(float %x) nounwind {
+; CHECK-LABEL: fabs_is_nonneg_or_nan:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fabs.s fa5, fa0
+; CHECK-NEXT:    fclass.s a0, fa5
+; CHECK-NEXT:    andi a0, a0, 1008
+; CHECK-NEXT:    snez a0, a0
+; CHECK-NEXT:    ret
+  %a = call float @llvm.fabs.f32(float %x)
+  %res = call i1 @llvm.is.fpclass.f32(float %a, i32 963)  ; 0x3C3 = any positive | nan
+  ret i1 %res
+}
+
 define <vscale x 4 x i1> @splat_constant_is_pos_normal() {
 ; CHECK-LABEL: splat_constant_is_pos_normal:
 ; CHECK:       # %bb.0:

>From 561f7ea39addbb79ea80a85de26d0ab27f49af99 Mon Sep 17 00:00:00 2001
From: xinlongchen <xinlongchen at tencent.com>
Date: Thu, 23 Apr 2026 21:24:14 +0800
Subject: [PATCH 2/2] add constant fold

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 ++++
 llvm/test/CodeGen/RISCV/combine-is_fpclass.ll | 5 +----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 20ff48789152b..e85be19d8abc6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16137,6 +16137,10 @@ SDValue DAGCombiner::visitIS_FPCLASS(SDNode *N) {
 
   KnownFPClass Known = DAG.computeKnownFPClass(Src, Mask);
 
+  // All possible classes are within the mask: result is always true.
+  if ((~Mask & Known.KnownFPClasses) == fcNone)
+    return DAG.getBoolConstant(true, DL, VT, Src.getValueType());
+
   // Clear test bits we know must be false from the source value.
   // fp_class (nnan x), qnan|snan|other -> fp_class (nnan x), other
   // fp_class (ninf x), ninf|pinf|other -> fp_class (ninf x), other
diff --git a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
index d325f9563f6c3..99c0be5b9692b 100644
--- a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
+++ b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
@@ -189,10 +189,7 @@ define i1 @extract_scalable_fabs_isneg(<vscale x 4 x float> %a0) nounwind {
 define i1 @fabs_is_nonneg_or_nan(float %x) nounwind {
 ; CHECK-LABEL: fabs_is_nonneg_or_nan:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fabs.s fa5, fa0
-; CHECK-NEXT:    fclass.s a0, fa5
-; CHECK-NEXT:    andi a0, a0, 1008
-; CHECK-NEXT:    snez a0, a0
+; CHECK-NEXT:    li a0, 1
 ; CHECK-NEXT:    ret
   %a = call float @llvm.fabs.f32(float %x)
   %res = call i1 @llvm.is.fpclass.f32(float %a, i32 963)  ; 0x3C3 = any positive | nan



More information about the llvm-commits mailing list