[llvm] eae1ec7 - [SelectionDAG] Handle scalable INSERT_SUBVECTOR in ComputeNumSignBits (#221631)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 04:24:15 PDT 2026
Author: Pkuyo
Date: 2026-09-13T13:24:10+02:00
New Revision: eae1ec7b1d6752d7d94214e4beaf724ce560aed2
URL: https://github.com/llvm/llvm-project/commit/eae1ec7b1d6752d7d94214e4beaf724ce560aed2
DIFF: https://github.com/llvm/llvm-project/commit/eae1ec7b1d6752d7d94214e4beaf724ce560aed2.diff
LOG: [SelectionDAG] Handle scalable INSERT_SUBVECTOR in ComputeNumSignBits (#221631)
Handle scalable INSERT_SUBVECTOR in SelectionDAG as a pre-fix for
#220976.
Add coverage for scalable subvectors and fixed subvectors inserted into
scalable vectors.
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/test/CodeGen/AArch64/sve-insert-vector.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index cc5356d6f1b93..66a445ec0827e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5455,12 +5455,15 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
return Tmp;
}
case ISD::INSERT_SUBVECTOR: {
- if (VT.isScalableVector())
- break;
- // Demand any elements from the subvector and the remainder from the src its
- // inserted into.
SDValue Src = Op.getOperand(0);
SDValue Sub = Op.getOperand(1);
+ if (VT.isScalableVector()) {
+ Tmp = ComputeNumSignBits(Sub, Depth + 1);
+ Tmp = std::min(Tmp, ComputeNumSignBits(Src, Depth + 1));
+ return Tmp;
+ }
+ // Demand any elements from the subvector and the remainder from the src its
+ // inserted into.
uint64_t Idx = Op.getConstantOperandVal(2);
unsigned NumSubElts = Sub.getValueType().getVectorNumElements();
APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
diff --git a/llvm/test/CodeGen/AArch64/sve-insert-vector.ll b/llvm/test/CodeGen/AArch64/sve-insert-vector.ll
index 9aebf291c0b3e..041a065687b05 100644
--- a/llvm/test/CodeGen/AArch64/sve-insert-vector.ll
+++ b/llvm/test/CodeGen/AArch64/sve-insert-vector.ll
@@ -1543,4 +1543,79 @@ define <vscale x 4 x float> @insert_nxv1f32_nxv4f32_3(<vscale x 4 x float> %vec,
ret <vscale x 4 x float> %retval
}
+define <vscale x 4 x i32> @insert_nxv4i32_nxv2i32_signbits(<vscale x 4 x i32> %vec, <vscale x 4 x i32> %subvec) {
+; CHECK-LABEL: insert_nxv4i32_nxv2i32_signbits:
+; CHECK: // %bb.0:
+; CHECK-NEXT: asr z0.s, z0.s, #24
+; CHECK-NEXT: asr z1.s, z1.s, #16
+; CHECK-NEXT: uunpklo z1.d, z1.s
+; CHECK-NEXT: uunpkhi z0.d, z0.s
+; CHECK-NEXT: uzp1 z0.s, z1.s, z0.s
+; CHECK-NEXT: ret
+ %base = ashr <vscale x 4 x i32> %vec, splat (i32 24)
+ %sub0 = ashr <vscale x 4 x i32> %subvec, splat (i32 16)
+ %sub = call <vscale x 2 x i32> @llvm.vector.extract.nxv2i32.nxv4i32(<vscale x 4 x i32> %sub0, i64 0)
+ %res = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv2i32(<vscale x 4 x i32> %base, <vscale x 2 x i32> %sub, i64 0)
+ %shl = shl <vscale x 4 x i32> %res, splat (i32 16)
+ %sext = ashr <vscale x 4 x i32> %shl, splat (i32 16)
+ ret <vscale x 4 x i32> %sext
+}
+
+define <vscale x 4 x i32> @insert_nxv4i32_v2i32_signbits(<vscale x 4 x i32> %vec, <4 x i32> %subvec) {
+; CHECK-LABEL: insert_nxv4i32_v2i32_signbits:
+; CHECK: // %bb.0:
+; CHECK-NEXT: asr z0.s, z0.s, #24
+; CHECK-NEXT: sshr v1.2s, v1.2s, #16
+; CHECK-NEXT: ptrue p0.s, vl2
+; CHECK-NEXT: mov z0.s, p0/m, z1.s
+; CHECK-NEXT: ret
+ %base = ashr <vscale x 4 x i32> %vec, splat (i32 24)
+ %sub0 = ashr <4 x i32> %subvec, splat (i32 16)
+ %sub = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %sub0, i64 0)
+ %res = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v2i32(<vscale x 4 x i32> %base, <2 x i32> %sub, i64 0)
+ %shl = shl <vscale x 4 x i32> %res, splat (i32 16)
+ %sext = ashr <vscale x 4 x i32> %shl, splat (i32 16)
+ ret <vscale x 4 x i32> %sext
+}
+
+define <vscale x 4 x i32> @insert_nxv4i32_nxv2i32_signbits_insufficient_base(<vscale x 4 x i32> %vec, <vscale x 4 x i32> %subvec) {
+; CHECK-LABEL: insert_nxv4i32_nxv2i32_signbits_insufficient_base:
+; CHECK: // %bb.0:
+; CHECK-NEXT: asr z0.s, z0.s, #15
+; CHECK-NEXT: asr z1.s, z1.s, #16
+; CHECK-NEXT: ptrue p0.s
+; CHECK-NEXT: uunpklo z1.d, z1.s
+; CHECK-NEXT: uunpkhi z0.d, z0.s
+; CHECK-NEXT: uzp1 z0.s, z1.s, z0.s
+; CHECK-NEXT: sxth z0.s, p0/m, z0.s
+; CHECK-NEXT: ret
+ %base = ashr <vscale x 4 x i32> %vec, splat (i32 15)
+ %sub0 = ashr <vscale x 4 x i32> %subvec, splat (i32 16)
+ %sub = call <vscale x 2 x i32> @llvm.vector.extract.nxv2i32.nxv4i32(<vscale x 4 x i32> %sub0, i64 0)
+ %res = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv2i32(<vscale x 4 x i32> %base, <vscale x 2 x i32> %sub, i64 0)
+ %shl = shl <vscale x 4 x i32> %res, splat (i32 16)
+ %sext = ashr <vscale x 4 x i32> %shl, splat (i32 16)
+ ret <vscale x 4 x i32> %sext
+}
+
+define <vscale x 4 x i32> @insert_nxv4i32_nxv2i32_signbits_insufficient_sub(<vscale x 4 x i32> %vec, <vscale x 4 x i32> %subvec) {
+; CHECK-LABEL: insert_nxv4i32_nxv2i32_signbits_insufficient_sub:
+; CHECK: // %bb.0:
+; CHECK-NEXT: asr z0.s, z0.s, #24
+; CHECK-NEXT: asr z1.s, z1.s, #15
+; CHECK-NEXT: ptrue p0.s
+; CHECK-NEXT: uunpklo z1.d, z1.s
+; CHECK-NEXT: uunpkhi z0.d, z0.s
+; CHECK-NEXT: uzp1 z0.s, z1.s, z0.s
+; CHECK-NEXT: sxth z0.s, p0/m, z0.s
+; CHECK-NEXT: ret
+ %base = ashr <vscale x 4 x i32> %vec, splat (i32 24)
+ %sub0 = ashr <vscale x 4 x i32> %subvec, splat (i32 15)
+ %sub = call <vscale x 2 x i32> @llvm.vector.extract.nxv2i32.nxv4i32(<vscale x 4 x i32> %sub0, i64 0)
+ %res = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv2i32(<vscale x 4 x i32> %base, <vscale x 2 x i32> %sub, i64 0)
+ %shl = shl <vscale x 4 x i32> %res, splat (i32 16)
+ %sext = ashr <vscale x 4 x i32> %shl, splat (i32 16)
+ ret <vscale x 4 x i32> %sext
+}
+
attributes #0 = { vscale_range(2,2) }
More information about the llvm-commits
mailing list