[llvm] [DAG] computeKnownFPClass - add ISD::EXTRACT_SUBVECTOR/INSERT_SUBVECTOR handling. (PR #190378)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 4 22:26:06 PDT 2026
https://github.com/Xylecrack updated https://github.com/llvm/llvm-project/pull/190378
>From 26450039fd4e20865bbed52142901a8063f6cb05 Mon Sep 17 00:00:00 2001
From: Dhruva Narayan <dhruvakodiadka at gmail.com>
Date: Sun, 5 Apr 2026 10:45:58 +0530
Subject: [PATCH 1/2] baseline tests
---
llvm/test/CodeGen/RISCV/combine-is_fpclass.ll | 110 ++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
index 0292df415a655..d8b8adfe376b3 100644
--- a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
+++ b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
@@ -21,3 +21,113 @@ define i8 @iszero_constant_v4f32() nounwind {
%r = bitcast <8 x i1> %f to i8
ret i8 %r
}
+
+define i1 @extract_subvec(<8 x float> %a0){
+; CHECK-LABEL: extract_subvec:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vfabs.v v8, v8
+; CHECK-NEXT: vsetivli zero, 4, e32, m2, ta, ma
+; CHECK-NEXT: vslidedown.vi v8, v8, 4
+; CHECK-NEXT: vfmv.f.s fa5, v8
+; CHECK-NEXT: fclass.s a0, fa5
+; CHECK-NEXT: andi a0, a0, 15
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: ret
+ %abs = call <8 x float> @llvm.fabs.v8f32(<8 x float> %a0)
+ %sub = call <4 x float> @llvm.vector.extract.v4f32.v8f32(<8 x float> %abs, i64 4)
+ %elt = extractelement <4 x float> %sub, i32 0
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 60)
+ ret i1 %res
+}
+
+define i1 @extract_subvec_scalable(<vscale x 8 x float> %a0){
+; CHECK-LABEL: extract_subvec_scalable:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfabs.v v8, v8
+; CHECK-NEXT: vfmv.f.s fa5, v8
+; CHECK-NEXT: fclass.s a0, fa5
+; CHECK-NEXT: andi a0, a0, 15
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: ret
+ %abs = call <vscale x 8 x float> @llvm.fabs.nxv8f32(<vscale x 8 x float> %a0)
+ %sub = call <vscale x 4 x float> @llvm.vector.extract.nxv4f32.nxv8f32(<vscale x 8 x float> %abs, i64 0)
+ %elt = extractelement <vscale x 4 x float> %sub, i32 0
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 60)
+ ret i1 %res
+}
+
+define <4 x i1> @insert_subvec_base_demanded(<4 x float> %base, <2 x float> %sub){
+; CHECK-LABEL: insert_subvec_base_demanded:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vfabs.v v8, v8
+; CHECK-NEXT: vslideup.vi v8, v9, 2
+; CHECK-NEXT: vfclass.v v8, v8
+; CHECK-NEXT: vand.vi v8, v8, 15
+; CHECK-NEXT: vmsne.vi v0, v8, 0
+; CHECK-NEXT: ret
+ %absbase = call <4 x float> @llvm.fabs.v4f32(<4 x float> %base)
+ %ins = call <4 x float> @llvm.vector.insert.v4f32.v2f32(<4 x float> %absbase, <2 x float> %sub, i64 2)
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %ins, i32 60)
+ ret <4 x i1> %res
+}
+
+define i1 @insert_subvec_sub_demanded(<4 x float> %base, <2 x float> %sub){
+; CHECK-LABEL: insert_subvec_sub_demanded:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vfabs.v v8, v9
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vslideup.vi v9, v8, 2
+; CHECK-NEXT: vslidedown.vi v8, v9, 2
+; CHECK-NEXT: vfmv.f.s fa5, v8
+; CHECK-NEXT: fclass.s a0, fa5
+; CHECK-NEXT: andi a0, a0, 15
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: ret
+ %abssub = call <2 x float> @llvm.fabs.v2f32(<2 x float> %sub)
+ %ins = call <4 x float> @llvm.vector.insert.v4f32.v2f32(<4 x float> %base, <2 x float> %abssub, i64 2)
+ %elt = extractelement <4 x float> %ins, i32 2
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 60)
+ ret i1 %res
+}
+
+define <4 x i1> @insert_subvec_both_demanded(<4 x float> %base, <2 x float> %sub){
+; CHECK-LABEL: insert_subvec_both_demanded:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vfabs.v v8, v8
+; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; CHECK-NEXT: vfabs.v v9, v9
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vslideup.vi v8, v9, 2
+; CHECK-NEXT: vfclass.v v8, v8
+; CHECK-NEXT: vand.vi v8, v8, 15
+; CHECK-NEXT: vmsne.vi v0, v8, 0
+; CHECK-NEXT: ret
+ %absbase = call <4 x float> @llvm.fabs.v4f32(<4 x float> %base)
+ %abssub = call <2 x float> @llvm.fabs.v2f32(<2 x float> %sub)
+ %ins = call <4 x float> @llvm.vector.insert.v4f32.v2f32(<4 x float> %absbase, <2 x float> %abssub, i64 2)
+ %res = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %ins, i32 60)
+ ret <4 x i1> %res
+}
+
+define i1 @insert_subvec_scalable_both(<vscale x 4 x float> %base, <vscale x 2 x float> %sub){
+; CHECK-LABEL: insert_subvec_scalable_both:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma
+; CHECK-NEXT: vfabs.v v8, v10
+; CHECK-NEXT: vfmv.f.s fa5, v8
+; CHECK-NEXT: fclass.s a0, fa5
+; CHECK-NEXT: andi a0, a0, 15
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: ret
+ %absbase = call <vscale x 4 x float> @llvm.fabs.nxv4f32(<vscale x 4 x float> %base)
+ %abssub = call <vscale x 2 x float> @llvm.fabs.nxv2f32(<vscale x 2 x float> %sub)
+ %ins = call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.nxv2f32(<vscale x 4 x float> %absbase, <vscale x 2 x float> %abssub, i64 0)
+ %elt = extractelement <vscale x 4 x float> %ins, i32 0
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 60)
+ ret i1 %res
+}
>From a631242018b9cbe0e1f43ca9751b3ad51ef651d7 Mon Sep 17 00:00:00 2001
From: Dhruva Narayan <dhruvakodiadka at gmail.com>
Date: Sun, 5 Apr 2026 10:53:54 +0530
Subject: [PATCH 2/2] add EXTRACT_SUBVECTOR/INSERT_SUBVECTOR handling in
computeKnownFPclass
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 43 +++++++++++++++++++
llvm/test/CodeGen/RISCV/combine-is_fpclass.ll | 11 +----
2 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6eb8853550a19..a25c7a201d954 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6100,6 +6100,49 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
Known.fabs();
break;
}
+ case ISD::EXTRACT_SUBVECTOR: {
+ SDValue Src = Op.getOperand(0);
+ EVT SrcVT = Src.getValueType();
+ if (SrcVT.isFixedLengthVector()) {
+ unsigned Idx = Op.getConstantOperandVal(1);
+ unsigned NumSrcElts = SrcVT.getVectorNumElements();
+
+ APInt DemandedSrcElts = DemandedElts.zextOrTrunc(NumSrcElts).shl(Idx);
+ Known = computeKnownFPClass(Src, DemandedSrcElts, InterestedClasses,
+ Depth + 1);
+ } else {
+ Known = computeKnownFPClass(Src, InterestedClasses, Depth + 1);
+ }
+ break;
+ }
+ case ISD::INSERT_SUBVECTOR: {
+ SDValue BaseVector = Op.getOperand(0);
+ SDValue SubVector = Op.getOperand(1);
+ EVT BaseVT = BaseVector.getValueType();
+ if (BaseVT.isFixedLengthVector()) {
+ unsigned Idx = Op.getConstantOperandVal(2);
+ unsigned NumBaseElts = BaseVT.getVectorNumElements();
+ unsigned NumSubElts = SubVector.getValueType().getVectorNumElements();
+
+ APInt DemandedMask =
+ APInt::getBitsSet(NumBaseElts, Idx, Idx + NumSubElts);
+ APInt DemandedSrcElts = DemandedElts & ~DemandedMask;
+ APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
+
+ if (!DemandedSrcElts.isZero())
+ Known = computeKnownFPClass(BaseVector, DemandedSrcElts,
+ InterestedClasses, Depth + 1);
+ if (!DemandedSubElts.isZero()) {
+ KnownFPClass SubKnown = computeKnownFPClass(
+ SubVector, DemandedSubElts, InterestedClasses, Depth + 1);
+ Known = DemandedSrcElts.isZero() ? SubKnown : (Known | SubKnown);
+ }
+ } else {
+ Known = computeKnownFPClass(BaseVector, InterestedClasses, Depth + 1) |
+ computeKnownFPClass(SubVector, InterestedClasses, Depth + 1);
+ }
+ break;
+ }
default:
if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
diff --git a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
index d8b8adfe376b3..955c40e1730d1 100644
--- a/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
+++ b/llvm/test/CodeGen/RISCV/combine-is_fpclass.ll
@@ -97,15 +97,8 @@ define i1 @insert_subvec_sub_demanded(<4 x float> %base, <2 x float> %sub){
define <4 x i1> @insert_subvec_both_demanded(<4 x float> %base, <2 x float> %sub){
; CHECK-LABEL: insert_subvec_both_demanded:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; CHECK-NEXT: vfabs.v v8, v8
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vfabs.v v9, v9
-; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; CHECK-NEXT: vslideup.vi v8, v9, 2
-; CHECK-NEXT: vfclass.v v8, v8
-; CHECK-NEXT: vand.vi v8, v8, 15
-; CHECK-NEXT: vmsne.vi v0, v8, 0
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vmclr.m v0
; CHECK-NEXT: ret
%absbase = call <4 x float> @llvm.fabs.v4f32(<4 x float> %base)
%abssub = call <2 x float> @llvm.fabs.v2f32(<2 x float> %sub)
More information about the llvm-commits
mailing list