-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[IR] Add TargetExtType::CanBeLocal property #99016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-llvm-ir Author: Jay Foad (jayfoad) ChangesAdd a property to allow marking target extension types that cannot be Full diff: https://github.com/llvm/llvm-project/pull/99016.diff 4 Files Affected:
diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index 01f76d4932780..054cb370bc316 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -769,6 +769,8 @@ class TargetExtType : public Type {
HasZeroInit = 1U << 0,
/// This type may be used as the value type of a global variable.
CanBeGlobal = 1U << 1,
+ /// This type may be used as the allocated type of an alloca instruction.
+ CanBeAlloca = 1U << 2,
};
/// 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 5c61ad9f000b0..3f982ef520e92 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -838,12 +838,14 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::CanBeGlobal);
if (Name.starts_with("spirv."))
return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::HasZeroInit,
- TargetExtType::CanBeGlobal);
+ TargetExtType::CanBeGlobal,
+ TargetExtType::CanBeAlloca);
// Opaque types in the AArch64 name space.
if (Name == "aarch64.svcount")
return TargetTypeInfo(ScalableVectorType::get(Type::getInt1Ty(C), 16),
- TargetExtType::HasZeroInit);
+ TargetExtType::HasZeroInit,
+ TargetExtType::CanBeAlloca);
return TargetTypeInfo(Type::getVoidTy(C));
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 75a53c1c99734..e59dc6bf24d38 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4273,6 +4273,12 @@ void Verifier::visitAllocaInst(AllocaInst &AI) {
SmallPtrSet<Type*, 4> Visited;
Check(AI.getAllocatedType()->isSized(&Visited),
"Cannot allocate unsized type", &AI);
+ // Check if it's a target extension type that disallows being used in an
+ // alloca.
+ if (auto *TTy = dyn_cast<TargetExtType>(AI.getAllocatedType())) {
+ Check(TTy->hasProperty(TargetExtType::CanBeAlloca),
+ "Alloca has illegal target extension type", &AI);
+ }
Check(AI.getArraySize()->getType()->isIntegerTy(),
"Alloca array size must have integer type", &AI);
if (MaybeAlign A = AI.getAlign()) {
diff --git a/llvm/test/Assembler/target-type-properties.ll b/llvm/test/Assembler/target-type-properties.ll
index 49c9d812f1cf4..eae5eec04da85 100644
--- a/llvm/test/Assembler/target-type-properties.ll
+++ b/llvm/test/Assembler/target-type-properties.ll
@@ -1,6 +1,7 @@
; RUN: split-file %s %t
; RUN: not llvm-as < %t/zeroinit-error.ll -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-ZEROINIT %s
; RUN: not llvm-as < %t/global-var.ll -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-GLOBALVAR %s
+; RUN: not llvm-as < %t/alloca.ll -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-ALLOCA %s
; Check target extension type properties are verified in the assembler.
;--- zeroinit-error.ll
@@ -14,3 +15,10 @@ define void @foo() {
;--- global-var.ll
@global = external global target("unknown_target_type")
; CHECK-GLOBALVAR: Global @global has illegal target extension type
+
+;--- alloca.ll
+define void @foo() {
+ %val = alloca target("spirv.Image")
+; CHECK-ALLOCA: Alloca has illegal target extension type
+ ret void
+}
|
llvm/lib/IR/Type.cpp
Outdated
@@ -838,12 +838,14 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) { | |||
return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::CanBeGlobal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a complete guess here that spirv.Image should not be used in allocas, so that I could use it as a test case. Please let me know if I got that wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @jcranmer-intel can comment on which spirv.
types can/cannot be used in allocas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are now some tests which do use spirv.Image in allocas:
test/CodeGen/SPIRV/transcoding/image_with_access_qualifiers.ll
test/CodeGen/SPIRV/transcoding/get_image_num_mip_levels.ll
test/CodeGen/SPIRV/image-unoptimized.ll
test/CodeGen/SPIRV/read_image.ll
@jcranmer-intel any comments on the validity of this? Is it a supported use of spirv.Image, or just something that was conventient for these test cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of this I don't have any non-CanBeLocal types to test with, so the tests I added in type/Assembler/target-type-properties.ll
are currently failing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm now using the newly added amdgcn.named.barrier
for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use case here is specifically a type that is sized but cannot be used in alloca?
What about use in byval?
Yes. The use case I am interested in is special global objects that correspond to hardware resources that will be statically allocated by the backend. They can never be dynamically allocated.
We definitely don't want them in byval - thanks! Perhaps |
What's the status of this? It seems reasonable to me. In terms of the name, I would slightly prefer something that relaxes restrictions instead of adding them, so perhaps |
Add a property to allow marking target extension types that cannot be used in an alloca instruction, similar to CanBeGlobal for global variables.
I went for |
llvm/lib/IR/Verifier.cpp
Outdated
// stack. | ||
if (auto *TTy = dyn_cast<TargetExtType>(AI.getAllocatedType())) { | ||
Check(TTy->hasProperty(TargetExtType::CanBeLocal), | ||
"Alloca has illegal target extension type", &AI); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also applies to the existing CanBeGlobal check, but this probably needs to be recursive? We'd not want to forbid target("foo")
but then allow { target("foo") }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I asked about that here: https://discourse.llvm.org/t/rfc-adding-opaque-types-to-llvm-ir/65326/25
I might work on it but I want to keep that separate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#116639 does this for CanBeGlobal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now added the recursive checks to this patch too.
Ping. This is ready again for review. |
SCDB_ContainsNonLocalTargetExtType = 64, | ||
SCDB_NotContainsNonLocalTargetExtType = 128, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I'm not sure if it's really worth adding these flags, just for an IR verifier check. I guess it accelerates recursive checking of pathological struct types with lots of repeated element types.
Add a property to allow marking target extension types that cannot be
used in an alloca instruction or byval argument, similar to CanBeGlobal
for global variables.