Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/IR/DerivedTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
25 changes: 20 additions & 5 deletions llvm/lib/IR/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,8 +790,12 @@ VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
}

bool VectorType::isValidElementType(Type *ElemTy) {
return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID;
if (ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
ElemTy->isPointerTy() || ElemTy->getTypeID() == TypedPointerTyID)
return true;
if (auto *TTy = dyn_cast<TargetExtType>(ElemTy))
return TTy->hasProperty(TargetExtType::CanBeVectorElement);
return false;
}

//===----------------------------------------------------------------------===//
Expand All @@ -801,8 +805,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);

Expand Down Expand Up @@ -968,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");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps?

Suggested change
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

Expand Down Expand Up @@ -1037,6 +1045,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));
}

Expand Down
8 changes: 8 additions & 0 deletions llvm/test/Verifier/target-ext-vector-invalid.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-disable-output instead of -o /dev/null


; CHECK: invalid vector element type

define void @bad() {
%v = alloca <2 x target("spirv.Image")>
ret void
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline error

20 changes: 20 additions & 0 deletions llvm/test/Verifier/target-ext-vector.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=verify -S %s | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should run just llvm-as and be in test/Assembler. test/Verifier is for cases that fail


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")> 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")> poison, target("llvm.test.vectorelement") %elt, i64 1
ret <2 x target("llvm.test.vectorelement")> %res
}
Loading