[llvm] [DAG] computeKnownFPClass - add ISD::EXTRACT_VECTOR_ELT handling (PR #190307)
Xinlong Chen via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 19 01:24:04 PDT 2026
================
@@ -22,6 +22,168 @@ define i8 @iszero_constant_v4f32() nounwind {
ret i8 %r
}
+define i1 @extract_bitcast_sign_set_not_pos(<4 x i32> %bits, ptr %p) nounwind { ; elts 0,2 sign set, idx=0, ispos -> false
+; CHECK-LABEL: extract_bitcast_sign_set_not_pos:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vid.v v9
+; CHECK-NEXT: vsll.vi v9, v9, 31
+; CHECK-NEXT: lui a1, 524288
+; CHECK-NEXT: vrsub.vx v9, v9, a1
+; CHECK-NEXT: vor.vv v8, v8, v9
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %masked = or <4 x i32> %bits, <i32 u0x80000000, i32 0, i32 u0x80000000, i32 0>
+ %fvec = bitcast <4 x i32> %masked to <4 x float>
+ store <4 x float> %fvec, ptr %p
+ %elt = extractelement <4 x float> %fvec, i32 0
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 960) ; 0x3C0 = any positive
+ ret i1 %res
+}
+
+define i1 @extract_bitcast_unknown_sign_ispos(<4 x i32> %bits, ptr %p) nounwind { ; elts 0,2 sign set, idx=1 unknown sign, ispos -> cannot fold
+; CHECK-LABEL: extract_bitcast_unknown_sign_ispos:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vid.v v9
+; CHECK-NEXT: vsll.vi v9, v9, 31
+; CHECK-NEXT: lui a1, 524288
+; CHECK-NEXT: vrsub.vx v9, v9, a1
+; CHECK-NEXT: vor.vv v8, v8, v9
+; CHECK-NEXT: vslidedown.vi v9, v8, 1
+; CHECK-NEXT: vfmv.f.s fa5, v9
+; CHECK-NEXT: fclass.s a1, fa5
+; CHECK-NEXT: andi a1, a1, 240
+; CHECK-NEXT: snez a1, a1
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: mv a0, a1
+; CHECK-NEXT: ret
+ %masked = or <4 x i32> %bits, <i32 u0x80000000, i32 0, i32 u0x80000000, i32 0>
+ %fvec = bitcast <4 x i32> %masked to <4 x float>
+ store <4 x float> %fvec, ptr %p
+ %elt = extractelement <4 x float> %fvec, i32 1
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 960) ; 0x3C0 = any positive
+ ret i1 %res
+}
+
+define i1 @extract_bitcast_not_nan(<4 x i32> %bits, ptr %p) nounwind { ; elts 0,2 exp bit cleared (not NaN), idx=0, isnan -> false
+; CHECK-LABEL: extract_bitcast_not_nan:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lui a1, 786432
+; CHECK-NEXT: addi a1, a1, -1
+; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; CHECK-NEXT: vmv.v.x v9, a1
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vand.vv v8, v8, v9
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+ %masked = and <4 x i32> %bits, <i32 u0xBFFFFFFF, i32 -1, i32 u0xBFFFFFFF, i32 -1>
+ %fvec = bitcast <4 x i32> %masked to <4 x float>
+ store <4 x float> %fvec, ptr %p
+ %elt = extractelement <4 x float> %fvec, i32 0
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 3) ; 0x3 = nan
+ ret i1 %res
+}
+
+define i1 @extract_bitcast_maybe_nan(<4 x i32> %bits, ptr %p) nounwind { ; elts 0,2 exp bit cleared, idx=1 unchanged, isnan -> cannot fold
+; CHECK-LABEL: extract_bitcast_maybe_nan:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lui a1, 786432
+; CHECK-NEXT: addi a1, a1, -1
+; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; CHECK-NEXT: vmv.v.x v9, a1
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vand.vv v8, v8, v9
+; CHECK-NEXT: vslidedown.vi v9, v8, 1
+; CHECK-NEXT: vfmv.f.s fa5, v9
+; CHECK-NEXT: fclass.s a1, fa5
+; CHECK-NEXT: andi a1, a1, 768
+; CHECK-NEXT: snez a1, a1
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: mv a0, a1
+; CHECK-NEXT: ret
+ %masked = and <4 x i32> %bits, <i32 u0xBFFFFFFF, i32 -1, i32 u0xBFFFFFFF, i32 -1>
+ %fvec = bitcast <4 x i32> %masked to <4 x float>
+ store <4 x float> %fvec, ptr %p
+ %elt = extractelement <4 x float> %fvec, i32 1
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 3) ; 0x3 = nan
+ ret i1 %res
+}
+
+define i1 @extract_bitcast_unknown_idx_not_pos(<4 x i32> %bits, ptr %p, i32 %idx) nounwind { ; mixed sign, unknown idx, ispos -> cannot fold
+; CHECK-LABEL: extract_bitcast_unknown_idx_not_pos:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vid.v v9
+; CHECK-NEXT: lui a2, 524288
+; CHECK-NEXT: slli a1, a1, 32
+; CHECK-NEXT: vsll.vi v9, v9, 31
+; CHECK-NEXT: vrsub.vx v9, v9, a2
+; CHECK-NEXT: vor.vv v8, v8, v9
+; CHECK-NEXT: srli a1, a1, 32
+; CHECK-NEXT: vslidedown.vx v9, v8, a1
+; CHECK-NEXT: vfmv.f.s fa5, v9
+; CHECK-NEXT: fclass.s a1, fa5
+; CHECK-NEXT: andi a1, a1, 240
+; CHECK-NEXT: snez a1, a1
+; CHECK-NEXT: vse32.v v8, (a0)
+; CHECK-NEXT: mv a0, a1
+; CHECK-NEXT: ret
+ %masked = or <4 x i32> %bits, <i32 u0x80000000, i32 0, i32 u0x80000000, i32 0>
+ %fvec = bitcast <4 x i32> %masked to <4 x float>
+ store <4 x float> %fvec, ptr %p
+ %elt = extractelement <4 x float> %fvec, i32 %idx
+ %res = call i1 @llvm.is.fpclass.f32(float %elt, i32 960) ; 0x3C0 = any positive
+ ret i1 %res
+}
+
+define i1 @extract_bitcast_oob_idx(<4 x i32> %bits, ptr %p) nounwind { ; idx=6 (OOB) -> undef, isnan -> cannot fold
----------------
Xinlong-Chen wrote:
oob test cannot fold now; I will submit those as an another pr.
https://github.com/llvm/llvm-project/pull/190307
More information about the llvm-commits
mailing list