[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