[llvm] [LLVM][IR] Support target extension types in vectors (PR #140630)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 10:18:16 PDT 2025
https://github.com/arysef updated https://github.com/llvm/llvm-project/pull/140630
>From 78a86cf8c1ca1bc3f0336ae0dcf71fab5ef508b9 Mon Sep 17 00:00:00 2001
From: Aryan Sefidi <asefidi at microsoft.com>
Date: Mon, 19 May 2025 21:41:01 +0000
Subject: [PATCH 1/4] Support target extension types in vectors
---
llvm/lib/IR/Type.cpp | 3 ++-
llvm/test/Verifier/target-ext-vector-invalid.ll | 8 ++++++++
llvm/test/Verifier/target-ext-vector.ll | 11 +++++++++++
3 files changed, 21 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Verifier/target-ext-vector-invalid.ll
create mode 100644 llvm/test/Verifier/target-ext-vector.ll
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 4b43b52014484..852b4897ed013 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -791,7 +791,8 @@ VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
bool VectorType::isValidElementType(Type *ElemTy) {
return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
- ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID;
+ ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID ||
+ (ElemTy->isTargetExtTy() && ElemTy->isSized());
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/Verifier/target-ext-vector-invalid.ll b/llvm/test/Verifier/target-ext-vector-invalid.ll
new file mode 100644
index 0000000000000..2b6a785db986c
--- /dev/null
+++ b/llvm/test/Verifier/target-ext-vector-invalid.ll
@@ -0,0 +1,8 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+; CHECK: invalid vector element type
+
+define void @bad() {
+ %v = alloca <2 x target("spirv.IntegralConstant")>
+ ret void
+}
\ No newline at end of file
diff --git a/llvm/test/Verifier/target-ext-vector.ll b/llvm/test/Verifier/target-ext-vector.ll
new file mode 100644
index 0000000000000..a9129d4dfaa55
--- /dev/null
+++ b/llvm/test/Verifier/target-ext-vector.ll
@@ -0,0 +1,11 @@
+; RUN: llvm-as -o - %s | llvm-dis | FileCheck %s
+
+; CHECK-LABEL: @vec_ops(
+define <2 x target("spirv.Image")> @vec_ops(<2 x target("spirv.Image")> %x) {
+ %a = alloca <2 x target("spirv.Image")>
+ store <2 x target("spirv.Image")> %x, ptr %a
+ %load = load <2 x target("spirv.Image")>, ptr %a
+ %elt = extractelement <2 x target("spirv.Image")> %load, i64 0
+ %res = insertelement <2 x target("spirv.Image")> undef, target("spirv.Image") %elt, i64 1
+ ret <2 x target("spirv.Image")> %res
+}
\ No newline at end of file
>From 33244621c32114827800f2191d444c7f82043af1 Mon Sep 17 00:00:00 2001
From: Aryan Sefidi <asefidi at microsoft.com>
Date: Thu, 5 Jun 2025 20:42:26 +0000
Subject: [PATCH 2/4] add property to opt in to being a valid vector element
type
---
llvm/docs/LangRef.rst | 3 +-
llvm/include/llvm/IR/DerivedTypes.h | 2 ++
llvm/lib/IR/Type.cpp | 22 ++++++++++----
.../Verifier/target-ext-vector-invalid.ll | 2 +-
llvm/test/Verifier/target-ext-vector.ll | 29 ++++++++++++-------
5 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 0958f6a4b729b..e3b7c223b9c8d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -4438,7 +4438,8 @@ the type size is smaller than the type's store size.
< vscale x <# elements> x <elementtype> > ; Scalable vector
The number of elements is a constant integer value larger than 0;
-elementtype may be any integer, floating-point or pointer type. Vectors
+elementtype may be any integer, floating-point, pointer type, or a sized
+target extension type that has the `CanBeVectorElement` property. Vectors
of size zero are not allowed. For scalable vectors, the total number of
elements is a constant multiple (called vscale) of the specified number
of elements; vscale is a positive integer that is unknown at compile time
diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index 4d6bb1cfe3069..fa62bc09b61a3 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -845,6 +845,8 @@ class TargetExtType : public Type {
/// This type may be allocated on the stack, either as the allocated type
/// of an alloca instruction or as a byval function parameter.
CanBeLocal = 1U << 2,
+ // This type may be used as an element in a vector.
+ CanBeVectorElement = 1U << 3,
};
/// Returns true if the target extension type contains the given property.
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 852b4897ed013..7858e24f4fce7 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -790,9 +790,13 @@ VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
}
bool VectorType::isValidElementType(Type *ElemTy) {
- return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
- ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID ||
- (ElemTy->isTargetExtTy() && ElemTy->isSized());
+ if (ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
+ ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID)
+ return true;
+ if (auto *TTy = dyn_cast<TargetExtType>(ElemTy))
+ return TTy->hasProperty(TargetExtType::CanBeVectorElement) &&
+ TTy->isSized();
+ return false;
}
//===----------------------------------------------------------------------===//
@@ -802,8 +806,9 @@ bool VectorType::isValidElementType(Type *ElemTy) {
FixedVectorType *FixedVectorType::get(Type *ElementType, unsigned NumElts) {
assert(NumElts > 0 && "#Elements of a VectorType must be greater than 0");
assert(isValidElementType(ElementType) && "Element type of a VectorType must "
- "be an integer, floating point, or "
- "pointer type.");
+ "be an integer, floating point, "
+ "pointer type, or a valid target "
+ "extension type.");
auto EC = ElementCount::getFixed(NumElts);
@@ -1038,6 +1043,13 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
TargetExtType::CanBeGlobal);
}
+ // Type used to test vector element target extension property.
+ // Can be removed once a public target extension type uses CanBeVectorElement
+ if (Name == "llvm.test.vectorelement") {
+ return TargetTypeInfo(Type::getInt32Ty(C), TargetExtType::CanBeLocal,
+ TargetExtType::CanBeVectorElement);
+ }
+
return TargetTypeInfo(Type::getVoidTy(C));
}
diff --git a/llvm/test/Verifier/target-ext-vector-invalid.ll b/llvm/test/Verifier/target-ext-vector-invalid.ll
index 2b6a785db986c..59e3e78276a06 100644
--- a/llvm/test/Verifier/target-ext-vector-invalid.ll
+++ b/llvm/test/Verifier/target-ext-vector-invalid.ll
@@ -3,6 +3,6 @@
; CHECK: invalid vector element type
define void @bad() {
- %v = alloca <2 x target("spirv.IntegralConstant")>
+ %v = alloca <2 x target("spirv.Image")>
ret void
}
\ No newline at end of file
diff --git a/llvm/test/Verifier/target-ext-vector.ll b/llvm/test/Verifier/target-ext-vector.ll
index a9129d4dfaa55..43d8360f39da0 100644
--- a/llvm/test/Verifier/target-ext-vector.ll
+++ b/llvm/test/Verifier/target-ext-vector.ll
@@ -1,11 +1,20 @@
-; RUN: llvm-as -o - %s | llvm-dis | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=verify -S %s | FileCheck %s
-; CHECK-LABEL: @vec_ops(
-define <2 x target("spirv.Image")> @vec_ops(<2 x target("spirv.Image")> %x) {
- %a = alloca <2 x target("spirv.Image")>
- store <2 x target("spirv.Image")> %x, ptr %a
- %load = load <2 x target("spirv.Image")>, ptr %a
- %elt = extractelement <2 x target("spirv.Image")> %load, i64 0
- %res = insertelement <2 x target("spirv.Image")> undef, target("spirv.Image") %elt, i64 1
- ret <2 x target("spirv.Image")> %res
-}
\ No newline at end of file
+define <2 x target("llvm.test.vectorelement")> @vec_ops(<2 x target("llvm.test.vectorelement")> %x) {
+; CHECK-LABEL: define <2 x target("llvm.test.vectorelement")> @vec_ops(
+; CHECK-SAME: <2 x target("llvm.test.vectorelement")> [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = alloca <2 x target("llvm.test.vectorelement")>{{.*}}
+; CHECK-NEXT: store <2 x target("llvm.test.vectorelement")> [[X]], ptr [[A]], {{.*}}
+; CHECK-NEXT: [[LOAD:%.*]] = load <2 x target("llvm.test.vectorelement")>, ptr [[A]], {{.*}}
+; CHECK-NEXT: [[ELT:%.*]] = extractelement <2 x target("llvm.test.vectorelement")> [[LOAD]], i64 0
+; CHECK-NEXT: [[RES:%.*]] = insertelement <2 x target("llvm.test.vectorelement")> undef, target("llvm.test.vectorelement") [[ELT]], i64 1
+; CHECK-NEXT: ret <2 x target("llvm.test.vectorelement")> [[RES]]
+;
+ %a = alloca <2 x target("llvm.test.vectorelement")>
+ store <2 x target("llvm.test.vectorelement")> %x, ptr %a
+ %load = load <2 x target("llvm.test.vectorelement")>, ptr %a
+ %elt = extractelement <2 x target("llvm.test.vectorelement")> %load, i64 0
+ %res = insertelement <2 x target("llvm.test.vectorelement")> undef, target("llvm.test.vectorelement") %elt, i64 1
+ ret <2 x target("llvm.test.vectorelement")> %res
+}
>From 9ad6926092cab0c2d3323d00a42c1243eba21260 Mon Sep 17 00:00:00 2001
From: Aryan Sefidi <asefidi at microsoft.com>
Date: Fri, 6 Jun 2025 19:19:22 +0000
Subject: [PATCH 3/4] improve comments, move sized check into target type
creation
---
llvm/docs/LangRef.rst | 2 +-
llvm/lib/IR/Type.cpp | 10 ++++++----
llvm/test/Verifier/target-ext-vector.ll | 4 ++--
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index e3b7c223b9c8d..78604d0df6bc6 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -4439,7 +4439,7 @@ the type size is smaller than the type's store size.
The number of elements is a constant integer value larger than 0;
elementtype may be any integer, floating-point, pointer type, or a sized
-target extension type that has the `CanBeVectorElement` property. Vectors
+target extension type that has the ``CanBeVectorElement`` property. Vectors
of size zero are not allowed. For scalable vectors, the total number of
elements is a constant multiple (called vscale) of the specified number
of elements; vscale is a positive integer that is unknown at compile time
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 7858e24f4fce7..fd290c22d3183 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -794,8 +794,7 @@ bool VectorType::isValidElementType(Type *ElemTy) {
ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID)
return true;
if (auto *TTy = dyn_cast<TargetExtType>(ElemTy))
- return TTy->hasProperty(TargetExtType::CanBeVectorElement) &&
- TTy->isSized();
+ return TTy->hasProperty(TargetExtType::CanBeVectorElement);
return false;
}
@@ -974,7 +973,10 @@ struct TargetTypeInfo {
template <typename... ArgTys>
TargetTypeInfo(Type *LayoutType, ArgTys... Properties)
- : LayoutType(LayoutType), Properties((0 | ... | Properties)) {}
+ : LayoutType(LayoutType), Properties((0 | ... | Properties)) {
+ if (this->Properties & TargetExtType::CanBeVectorElement)
+ assert(LayoutType->isSized() && "Vector element type must be sized");
+ }
};
} // anonymous namespace
@@ -1044,7 +1046,7 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
}
// Type used to test vector element target extension property.
- // Can be removed once a public target extension type uses CanBeVectorElement
+ // Can be removed once a public target extension type uses CanBeVectorElement.
if (Name == "llvm.test.vectorelement") {
return TargetTypeInfo(Type::getInt32Ty(C), TargetExtType::CanBeLocal,
TargetExtType::CanBeVectorElement);
diff --git a/llvm/test/Verifier/target-ext-vector.ll b/llvm/test/Verifier/target-ext-vector.ll
index 43d8360f39da0..433715bc6c643 100644
--- a/llvm/test/Verifier/target-ext-vector.ll
+++ b/llvm/test/Verifier/target-ext-vector.ll
@@ -8,13 +8,13 @@ define <2 x target("llvm.test.vectorelement")> @vec_ops(<2 x target("llvm.test.v
; CHECK-NEXT: store <2 x target("llvm.test.vectorelement")> [[X]], ptr [[A]], {{.*}}
; CHECK-NEXT: [[LOAD:%.*]] = load <2 x target("llvm.test.vectorelement")>, ptr [[A]], {{.*}}
; CHECK-NEXT: [[ELT:%.*]] = extractelement <2 x target("llvm.test.vectorelement")> [[LOAD]], i64 0
-; CHECK-NEXT: [[RES:%.*]] = insertelement <2 x target("llvm.test.vectorelement")> undef, target("llvm.test.vectorelement") [[ELT]], i64 1
+; CHECK-NEXT: [[RES:%.*]] = insertelement <2 x target("llvm.test.vectorelement")> poison, target("llvm.test.vectorelement") [[ELT]], i64 1
; CHECK-NEXT: ret <2 x target("llvm.test.vectorelement")> [[RES]]
;
%a = alloca <2 x target("llvm.test.vectorelement")>
store <2 x target("llvm.test.vectorelement")> %x, ptr %a
%load = load <2 x target("llvm.test.vectorelement")>, ptr %a
%elt = extractelement <2 x target("llvm.test.vectorelement")> %load, i64 0
- %res = insertelement <2 x target("llvm.test.vectorelement")> undef, target("llvm.test.vectorelement") %elt, i64 1
+ %res = insertelement <2 x target("llvm.test.vectorelement")> poison, target("llvm.test.vectorelement") %elt, i64 1
ret <2 x target("llvm.test.vectorelement")> %res
}
>From 56639dcd678d6c133934e2159b268d5155da9c40 Mon Sep 17 00:00:00 2001
From: Aryan Sefidi <asefidi at microsoft.com>
Date: Mon, 9 Jun 2025 17:18:05 +0000
Subject: [PATCH 4/4] remove conditional, use only assert
---
llvm/lib/IR/Type.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index fd290c22d3183..7e64992c2dfe2 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -974,8 +974,9 @@ struct TargetTypeInfo {
template <typename... ArgTys>
TargetTypeInfo(Type *LayoutType, ArgTys... Properties)
: LayoutType(LayoutType), Properties((0 | ... | Properties)) {
- if (this->Properties & TargetExtType::CanBeVectorElement)
- assert(LayoutType->isSized() && "Vector element type must be sized");
+ assert((!(this->Properties & TargetExtType::CanBeVectorElement) ||
+ LayoutType->isSized()) &&
+ "Vector element type must be sized");
}
};
} // anonymous namespace
More information about the llvm-commits
mailing list