[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