[llvm] [GlobalISel] Add KnownBits support for G_INSERT_SUBVECTOR (PR #215048)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 8 19:34:03 PDT 2026


https://github.com/youssesef-I created https://github.com/llvm/llvm-project/pull/215048

## Summary

Add KnownBits support for `G_INSERT_SUBVECTOR` in GlobalISel value
tracking.

The implementation splits the demanded elements between the original
vector and inserted subvector, ignores overwritten source elements, and
intersects the KnownBits information from the contributing operands.

Part of #150515.

## Testing

- `llvm-lit llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-subvector.mir`
- `llvm-lit llvm/test/CodeGen/AArch64/GlobalISel/knownbits-*.mir`
  - 40/40 passed

>From dc12dfc9e920236032676485d41910ca3830680f Mon Sep 17 00:00:00 2001
From: Yousef Idris <yousef.idris01 at bcmail.cuny.edu>
Date: Sat, 8 Aug 2026 22:16:34 +0000
Subject: [PATCH] [GlobalISel] Add KnownBits support for G_INSERT_SUBVECTOR

---
 .../CodeGen/GlobalISel/GISelValueTracking.cpp | 36 +++++++++
 .../GlobalISel/knownbits-insert-subvector.mir | 73 +++++++++++++++++++
 2 files changed, 109 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-subvector.mir

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 139d70f28a4d9..8b0c67411ce79 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1064,6 +1064,42 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     }
     break;
   }
+					  
+    case TargetOpcode::G_INSERT_SUBVECTOR: {
+	GInsertSubvector &Insert = cast<GInsertSubvector>(MI);
+
+	Register Src = Insert.getBigVec();
+	Register Sub = Insert.getSubVec();
+	uint64_t Idx = Insert.getIndexImm();
+
+	LLT SrcTy = MRI.getType(Src);
+
+	if (SrcTy.isScalableVector())
+	    break;
+
+	LLT SubTy = MRI.getType(Sub);
+	unsigned NumSubElts = SubTy.getNumElements();
+	APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
+	APInt DemandedSrcElts = DemandedElts;
+	DemandedSrcElts.clearBits(Idx, Idx + NumSubElts);
+
+	Known.setAllConflict();
+	if (!!DemandedSubElts) {
+	    computeKnownBitsImpl(Sub, Known2, DemandedSubElts, Depth + 1);
+	    Known = Known.intersectWith(Known2);
+
+	    if (Known.isUnknown())
+		break;
+	}
+	if (!!DemandedSrcElts) {
+	    computeKnownBitsImpl(Src, Known2, DemandedSrcElts, Depth + 1);
+	    Known = Known.intersectWith(Known2);
+	}
+
+	break;
+
+	}
+
   case TargetOpcode::G_SHUFFLE_VECTOR: {
     APInt DemandedLHS, DemandedRHS;
     // Collect the known bits that are shared by every vector element referenced
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-subvector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-subvector.mir
new file mode 100644
index 0000000000000..1bc662f7a8c31
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-subvector.mir
@@ -0,0 +1,73 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=aarch64 -passes="print<gisel-value-tracking>" -filetype=null %s 2>&1 | FileCheck %s
+
+---
+name: no_knownbits
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @no_knownbits
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+    %0:_(<4 x i8>) = COPY $s0
+    %1:_(<2 x i8>) = COPY $h1
+    %2:_(<4 x i8>) = G_INSERT_SUBVECTOR %0, %1, 2
+...
+---
+name: zext_insert_subvector
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @zext_insert_subvector
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %src:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %sub:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %res:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+    %0:_(<4 x i8>) = COPY $s0
+    %1:_(<2 x i8>) = COPY $h1
+    %src:_(<4 x i16>) = G_ZEXT %0
+    %sub:_(<2 x i16>) = G_ZEXT %1
+    %res:_(<4 x i16>) = G_INSERT_SUBVECTOR %src, %sub, 2
+...
+---
+name: overwritten_src_ignored
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @overwritten_src_ignored
+  ; CHECK-NEXT: %zero:_ KnownBits:0000000000000000 SignBits:16 IsKnownNeverZero:0
+  ; CHECK-NEXT: %bad0:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %bad1:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %src:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %sub:_ KnownBits:0000000000000000 SignBits:16 IsKnownNeverZero:0
+  ; CHECK-NEXT: %res:_ KnownBits:0000000000000000 SignBits:16 IsKnownNeverZero:0
+    %zero:_(s16) = G_CONSTANT i16 0
+    %bad0:_(s16) = COPY $h0
+    %bad1:_(s16) = COPY $h1
+
+    %src:_(<4 x i16>) = G_BUILD_VECTOR %zero, %zero, %bad0, %bad1
+    %sub:_(<2 x i16>) = G_BUILD_VECTOR %zero, %zero
+
+    %res:_(<4 x i16>) = G_INSERT_SUBVECTOR %src, %sub, 2
+...
+---
+name: intersect_src_and_sub
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @intersect_src_and_sub
+  ; CHECK-NEXT: %srcval:_ KnownBits:0000000011111111 SignBits:8 IsKnownNeverZero:1
+  ; CHECK-NEXT: %subval:_ KnownBits:0000111111111111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %bad0:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %bad1:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %src:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %sub:_ KnownBits:0000111111111111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %res:_ KnownBits:0000????11111111 SignBits:4 IsKnownNeverZero:1
+    %srcval:_(s16) = G_CONSTANT i16 255
+    %subval:_(s16) = G_CONSTANT i16 4095
+    %bad0:_(s16) = COPY $h0
+    %bad1:_(s16) = COPY $h1
+
+    %src:_(<4 x i16>) = G_BUILD_VECTOR %srcval, %srcval, %bad0, %bad1
+    %sub:_(<2 x i16>) = G_BUILD_VECTOR %subval, %subval
+
+    %res:_(<4 x i16>) = G_INSERT_SUBVECTOR %src, %sub, 2
+...



More information about the llvm-commits mailing list