[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