[llvm] [Verifier] Prevent insertion/extraction of scalable vectors into/from fixed vectors (PR #215647)

Sean Clarke via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 13:18:07 PDT 2026


https://github.com/xarkenz updated https://github.com/llvm/llvm-project/pull/215647

>From 52c2ce746484314f3eb6f7b0118b811704366bfe Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Tue, 11 Aug 2026 14:46:06 -0500
Subject: [PATCH 1/2] Prevent insertion/extraction of scalable into/from fixed

---
 llvm/lib/IR/Verifier.cpp                        | 14 ++++++++++++++
 .../insert-extract-intrinsics-invalid.ll        | 17 +++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 09429024e3ae8..54f5ab8b8af0f 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6841,6 +6841,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
           "vector_insert index must be a constant multiple of "
           "the subvector's known minimum vector length.");
 
+    // The only allowed 'mixed' case is inserting a fixed vector into a
+    // scalable vector.
+    if (SubVecEC.isScalable()) {
+      Check(VecEC.isScalable(), "Scalable vectors can only be inserted into "
+                                "other scalable vectors.");
+    }
+
     // If this insertion is not the 'mixed' case where a fixed vector is
     // inserted into a scalable vector, ensure that the insertion of the
     // subvector does not overrun the parent vector.
@@ -6871,6 +6878,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
           "vector_extract index must be a constant multiple of "
           "the result type's known minimum vector length.");
 
+    // The only allowed 'mixed' case is extracting a fixed vector from a
+    // scalable vector.
+    if (ResultEC.isScalable()) {
+      Check(VecEC.isScalable(), "Scalable vectors can only be extracted from "
+                                "other scalable vectors.");
+    }
+
     // If this extraction is not the 'mixed' case where a fixed vector is
     // extracted from a scalable vector, ensure that the extraction does not
     // overrun the parent vector.
diff --git a/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll b/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll
index 851828d61f955..3317105365b90 100644
--- a/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll
+++ b/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll
@@ -78,6 +78,23 @@ define <vscale x 8 x i32> @insert_overrun_scalable_fixed(<vscale x 8 x i32> %vec
   ret <vscale x 8 x i32> %1
 }
 
+;
+; Test that extractions/insertions of a scalable vector from/into a fixed vector
+; are captured.
+;
+
+; CHECK: Scalable vectors can only be extracted from other scalable vectors.
+define <vscale x 4 x i32> @extract_scalable_from_fixed(<8 x i32> %vec) {
+  %1 = call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.v8i32(<8 x i32> %vec, i64 0)
+  ret <vscale x 4 x i32> %1
+}
+
+; CHECK: Scalable vectors can only be inserted into other scalable vectors.
+define <8 x i32> @insert_scalable_into_fixed(<8 x i32> %vec, <vscale x 4 x i32> %subvec) {
+  %1 = call <8 x i32> @llvm.vector.insert.v8i32.nxv4i32(<8 x i32> %vec, <vscale x 4 x i32> %subvec, i64 0)
+  ret <8 x i32> %1
+}
+
 declare <vscale x 3 x i32> @llvm.vector.extract.nxv8i32.nxv3i32(<vscale x 8 x i32>, i64)
 declare <vscale x 8 x i32> @llvm.vector.insert.nxv8i32.nxv3i32(<vscale x 8 x i32>, <vscale x 3 x i32>, i64)
 declare <vscale x 8 x i32> @llvm.vector.insert.nxv8i32.v3i32(<vscale x 8 x i32>, <3 x i32>, i64)

>From a7ee64fbe72fbba10f664974279d2d990382dd31 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Tue, 11 Aug 2026 15:17:54 -0500
Subject: [PATCH 2/2] Add negative tests

---
 .../Verifier/insert-extract-intrinsics-invalid.ll    | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll b/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll
index 3317105365b90..5b05cd52c9b9c 100644
--- a/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll
+++ b/llvm/test/Verifier/insert-extract-intrinsics-invalid.ll
@@ -89,12 +89,24 @@ define <vscale x 4 x i32> @extract_scalable_from_fixed(<8 x i32> %vec) {
   ret <vscale x 4 x i32> %1
 }
 
+; CHECK-NOT: Scalable vectors can only be extracted from other scalable vectors.
+define <4 x i32> @extract_fixed_from_scalable(<vscale x 8 x i32> %vec) {
+  %1 = call <4 x i32> @llvm.vector.extract.v4i32.nxv8i32(<vscale x 8 x i32> %vec, i64 0)
+  ret <4 x i32> %1
+}
+
 ; CHECK: Scalable vectors can only be inserted into other scalable vectors.
 define <8 x i32> @insert_scalable_into_fixed(<8 x i32> %vec, <vscale x 4 x i32> %subvec) {
   %1 = call <8 x i32> @llvm.vector.insert.v8i32.nxv4i32(<8 x i32> %vec, <vscale x 4 x i32> %subvec, i64 0)
   ret <8 x i32> %1
 }
 
+; CHECK-NOT: Scalable vectors can only be inserted into other scalable vectors.
+define <vscale x 8 x i32> @insert_fixed_into_scalable(<vscale x 8 x i32> %vec, <4 x i32> %subvec) {
+  %1 = call <vscale x 8 x i32> @llvm.vector.insert.nxv8i32.v4i32(<vscale x 8 x i32> %vec, <4 x i32> %subvec, i64 0)
+  ret <vscale x 8 x i32> %1
+}
+
 declare <vscale x 3 x i32> @llvm.vector.extract.nxv8i32.nxv3i32(<vscale x 8 x i32>, i64)
 declare <vscale x 8 x i32> @llvm.vector.insert.nxv8i32.nxv3i32(<vscale x 8 x i32>, <vscale x 3 x i32>, i64)
 declare <vscale x 8 x i32> @llvm.vector.insert.nxv8i32.v3i32(<vscale x 8 x i32>, <3 x i32>, i64)



More information about the llvm-commits mailing list